rdflib.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2009 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. /* rdflib - manipulate RDOFF library files (.rdl) */
  34. /*
  35. * an rdoff library is simply a sequence of RDOFF object files, each
  36. * preceded by the name of the module, an ASCII string of up to 255
  37. * characters, terminated by a zero.
  38. *
  39. * When a library is being created, special signature block is placed
  40. * in the beginning of the file. It is a string 'RDLIB' followed by a
  41. * version number, then int32_t content size and a int32_t time stamp.
  42. * The module name of the signature block is '.sig'.
  43. *
  44. *
  45. * There may be an optional directory placed on the end of the file.
  46. * The format of the directory will be 'RDLDD' followed by a version
  47. * number, followed by the length of the directory, and then the
  48. * directory, the format of which has not yet been designed.
  49. * The module name of the directory must be '.dir'.
  50. *
  51. * All module names beginning with '.' are reserved for possible future
  52. * extensions. The linker ignores all such modules, assuming they have
  53. * the format of a six uint8_t type & version identifier followed by int32_t
  54. * content size, followed by data.
  55. */
  56. #include "compiler.h"
  57. #include "rdfutils.h"
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <errno.h>
  61. #include <string.h>
  62. #include <time.h>
  63. /* functions supported:
  64. * create a library (no extra operands required)
  65. * add a module from a library (requires filename and name to give mod.)
  66. * replace a module in a library (requires given name and filename)
  67. * delete a module from a library (requires given name)
  68. * extract a module from the library (requires given name and filename)
  69. * list modules
  70. */
  71. const char *usage =
  72. "usage:\n"
  73. " rdflib x libname [extra operands]\n\n"
  74. " where x is one of:\n"
  75. " c - create library\n"
  76. " a - add module (operands = filename module-name)\n"
  77. " x - extract (module-name filename)\n"
  78. " r - replace (module-name filename)\n"
  79. " d - delete (module-name)\n" " t - list\n";
  80. /* Library signature */
  81. const char *rdl_signature = "RDLIB2", *sig_modname = ".sig";
  82. char **_argv;
  83. #define _ENDIANNESS 0 /* 0 for little, 1 for big */
  84. static void int32_ttolocal(int32_t *l)
  85. {
  86. #if _ENDIANNESS
  87. uint8_t t;
  88. uint8_t *p = (uint8_t *)l;
  89. t = p[0];
  90. p[0] = p[3];
  91. p[3] = t;
  92. t = p[1];
  93. p[1] = p[2];
  94. p[2] = p[1];
  95. #else
  96. (void)l; /* placate optimizers */
  97. #endif
  98. }
  99. static char copybytes(FILE * fp, FILE * fp2, int n)
  100. {
  101. int i, t = 0;
  102. for (i = 0; i < n; i++) {
  103. t = fgetc(fp);
  104. if (t == EOF) {
  105. fprintf(stderr, "rdflib: premature end of file in '%s'\n",
  106. _argv[2]);
  107. exit(1);
  108. }
  109. if (fp2)
  110. if (fputc(t, fp2) == EOF) {
  111. fprintf(stderr, "rdflib: write error\n");
  112. exit(1);
  113. }
  114. }
  115. return (char)t; /* return last char read */
  116. }
  117. static int32_t copyint32_t(FILE * fp, FILE * fp2)
  118. {
  119. int32_t l;
  120. int i, t;
  121. uint8_t *p = (uint8_t *)&l;
  122. for (i = 0; i < 4; i++) { /* skip magic no */
  123. t = fgetc(fp);
  124. if (t == EOF) {
  125. fprintf(stderr, "rdflib: premature end of file in '%s'\n",
  126. _argv[2]);
  127. exit(1);
  128. }
  129. if (fp2)
  130. if (fputc(t, fp2) == EOF) {
  131. fprintf(stderr, "rdflib: write error\n");
  132. exit(1);
  133. }
  134. *p++ = t;
  135. }
  136. int32_ttolocal(&l);
  137. return l;
  138. }
  139. int main(int argc, char **argv)
  140. {
  141. FILE *fp, *fp2 = NULL, *fptmp;
  142. char *p, buf[256], c;
  143. int i;
  144. int32_t l;
  145. time_t t;
  146. char rdbuf[10];
  147. _argv = argv;
  148. if (argc < 3 || !strncmp(argv[1], "-h", 2)
  149. || !strncmp(argv[1], "--h", 3)) {
  150. fputs(usage, stdout);
  151. exit(1);
  152. }
  153. rdoff_init();
  154. switch (argv[1][0]) {
  155. case 'c': /* create library */
  156. fp = fopen(argv[2], "wb");
  157. if (!fp) {
  158. fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
  159. perror("rdflib");
  160. exit(1);
  161. }
  162. nasm_write(sig_modname, strlen(sig_modname) + 1, fp);
  163. nasm_write(rdl_signature, strlen(rdl_signature), fp);
  164. t = time(NULL);
  165. fwriteint32_t(t, fp);
  166. fclose(fp);
  167. break;
  168. case 'a': /* add module */
  169. if (argc < 5) {
  170. fprintf(stderr, "rdflib: required parameter missing\n");
  171. exit(1);
  172. }
  173. fp = fopen(argv[2], "ab");
  174. if (!fp) {
  175. fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
  176. perror("rdflib");
  177. exit(1);
  178. }
  179. fp2 = fopen(argv[3], "rb");
  180. if (!fp2) {
  181. fprintf(stderr, "rdflib: could not open '%s'\n", argv[3]);
  182. perror("rdflib");
  183. exit(1);
  184. }
  185. p = argv[4];
  186. do {
  187. if (fputc(*p, fp) == EOF) {
  188. fprintf(stderr, "rdflib: write error\n");
  189. exit(1);
  190. }
  191. } while (*p++);
  192. while (!feof(fp2)) {
  193. i = fgetc(fp2);
  194. if (i == EOF) {
  195. break;
  196. }
  197. if (fputc(i, fp) == EOF) {
  198. fprintf(stderr, "rdflib: write error\n");
  199. exit(1);
  200. }
  201. }
  202. fclose(fp2);
  203. fclose(fp);
  204. break;
  205. case 'x':
  206. if (argc < 5) {
  207. fprintf(stderr, "rdflib: required parameter missing\n");
  208. exit(1);
  209. }
  210. break;
  211. case 't':
  212. fp = fopen(argv[2], "rb");
  213. if (!fp) {
  214. fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
  215. perror("rdflib");
  216. exit(1);
  217. }
  218. fp2 = NULL;
  219. while (!feof(fp)) {
  220. /* read name */
  221. p = buf;
  222. while ((*(p++) = (char)fgetc(fp)))
  223. if (feof(fp))
  224. break;
  225. if (feof(fp))
  226. break;
  227. fp2 = NULL;
  228. if (argv[1][0] == 'x') {
  229. /* check against desired name */
  230. if (!strcmp(buf, argv[3])) {
  231. fp2 = fopen(argv[4], "wb");
  232. if (!fp2) {
  233. fprintf(stderr, "rdflib: could not open '%s'\n",
  234. argv[4]);
  235. perror("rdflib");
  236. exit(1);
  237. }
  238. }
  239. } else
  240. printf("%-40s ", buf);
  241. /* step over the RDOFF file, extracting type information for
  242. * the listing, and copying it if fp2 != NULL */
  243. if (buf[0] == '.') {
  244. if (argv[1][0] == 't')
  245. for (i = 0; i < 6; i++)
  246. printf("%c", copybytes(fp, fp2, 1));
  247. else
  248. copybytes(fp, fp2, 6);
  249. l = copyint32_t(fp, fp2);
  250. if (argv[1][0] == 't')
  251. printf(" %"PRId32" bytes content\n", l);
  252. copybytes(fp, fp2, l);
  253. } else if ((c = copybytes(fp, fp2, 6)) >= '2') { /* version 2 or above */
  254. l = copyint32_t(fp, fp2);
  255. if (argv[1][0] == 't')
  256. printf("RDOFF%c %"PRId32" bytes content\n", c, l);
  257. copybytes(fp, fp2, l); /* entire object */
  258. } else {
  259. if (argv[1][0] == 't')
  260. printf("RDOFF1\n");
  261. /*
  262. * version 1 object, so we don't have an object content
  263. * length field.
  264. */
  265. copybytes(fp, fp2, copyint32_t(fp, fp2)); /* header */
  266. copybytes(fp, fp2, copyint32_t(fp, fp2)); /* text */
  267. copybytes(fp, fp2, copyint32_t(fp, fp2)); /* data */
  268. }
  269. if (fp2)
  270. break;
  271. }
  272. fclose(fp);
  273. if (fp2)
  274. fclose(fp2);
  275. else if (argv[1][0] == 'x') {
  276. fprintf(stderr, "rdflib: module '%s' not found in '%s'\n",
  277. argv[3], argv[2]);
  278. exit(1);
  279. }
  280. break;
  281. case 'r': /* replace module */
  282. argc--;
  283. /* fall through */
  284. case 'd': /* delete module */
  285. if (argc < 4) {
  286. fprintf(stderr, "rdflib: required parameter missing\n");
  287. exit(1);
  288. }
  289. fp = fopen(argv[2], "rb");
  290. if (!fp) {
  291. fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
  292. perror("rdflib");
  293. exit(1);
  294. }
  295. if (argv[1][0] == 'r') {
  296. fp2 = fopen(argv[4], "rb");
  297. if (!fp2) {
  298. fprintf(stderr, "rdflib: could not open '%s'\n", argv[4]);
  299. perror("rdflib");
  300. exit(1);
  301. }
  302. }
  303. fptmp = tmpfile();
  304. if (!fptmp) {
  305. fprintf(stderr, "rdflib: could not open temporary file\n");
  306. perror("rdflib");
  307. exit(1);
  308. }
  309. /* copy library into temporary file */
  310. fseek(fp, 0, SEEK_END); /* get file length */
  311. l = ftell(fp);
  312. fseek(fp, 0, SEEK_SET);
  313. copybytes(fp, fptmp, l);
  314. rewind(fptmp);
  315. if (freopen(argv[2], "wb", fp) == NULL) {
  316. fprintf(stderr, "rdflib: could not reopen '%s'\n", argv[2]);
  317. perror("rdflib");
  318. exit(1);
  319. }
  320. while (!feof(fptmp)) {
  321. /* read name */
  322. p = buf;
  323. while ((*(p++) = (char)fgetc(fptmp)))
  324. if (feof(fptmp))
  325. break;
  326. if (feof(fptmp))
  327. break;
  328. /* check against desired name */
  329. if (!strcmp(buf, argv[3])) {
  330. if (fread(p = rdbuf, 1, sizeof(rdbuf), fptmp) < 10) {
  331. nasm_fatal(0, "short read on input");
  332. }
  333. l = *(int32_t *)(p + 6);
  334. fseek(fptmp, l, SEEK_CUR);
  335. break;
  336. } else {
  337. nasm_write(buf, strlen(buf) + 1, fp); /* module name */
  338. if ((c = copybytes(fptmp, fp, 6)) >= '2') {
  339. l = copyint32_t(fptmp, fp); /* version 2 or above */
  340. copybytes(fptmp, fp, l); /* entire object */
  341. }
  342. }
  343. }
  344. if (argv[1][0] == 'r') {
  345. /* copy new module into library */
  346. p = argv[3];
  347. do {
  348. if (fputc(*p, fp) == EOF) {
  349. fprintf(stderr, "rdflib: write error\n");
  350. exit(1);
  351. }
  352. } while (*p++);
  353. while (!feof(fp2)) {
  354. i = fgetc(fp2);
  355. if (i == EOF) {
  356. break;
  357. }
  358. if (fputc(i, fp) == EOF) {
  359. fprintf(stderr, "rdflib: write error\n");
  360. exit(1);
  361. }
  362. }
  363. fclose(fp2);
  364. }
  365. /* copy rest of library if any */
  366. while (!feof(fptmp)) {
  367. i = fgetc(fptmp);
  368. if (i == EOF) {
  369. break;
  370. }
  371. if (fputc(i, fp) == EOF) {
  372. fprintf(stderr, "rdflib: write error\n");
  373. exit(1);
  374. }
  375. }
  376. fclose(fp);
  377. fclose(fptmp);
  378. break;
  379. default:
  380. fprintf(stderr, "rdflib: command '%c' not recognized\n",
  381. argv[1][0]);
  382. exit(1);
  383. }
  384. return 0;
  385. }