archiver.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* ar - archiver Author: Michiel Huisjes */
  6. /* Made into arch/aal by Ceriel Jacobs
  7. */
  8. static char RcsId[] = "$Id$";
  9. /*
  10. * Usage: [arch|aal] [qdprtx][vlcu] archive [file] ...
  11. * v: verbose
  12. * x: extract
  13. * q: append
  14. * r: replace (append when not in archive)
  15. * d: delete
  16. * t: print contents of archive
  17. * p: print named files
  18. * l: temporaries in current directory instead of /tmp
  19. * c: don't give "create" message
  20. * u: replace only if dated later than member in archive
  21. #ifdef DISTRIBUTION
  22. * D: make distribution: use distr_time, uid=2, gid=2, mode=0644
  23. #endif
  24. */
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <signal.h>
  31. #include <arch.h>
  32. #include <ranlib.h>
  33. #ifdef AAL
  34. #include <out.h>
  35. #define MAGIC_NUMBER AALMAG
  36. long offset;
  37. struct ranlib *tab;
  38. unsigned int tnum = 0;
  39. char *tstrtab;
  40. unsigned int tssiz = 0;
  41. unsigned int tabsz, strtabsz;
  42. #else
  43. #define MAGIC_NUMBER ARMAG
  44. #endif
  45. #define odd(nr) (nr & 01)
  46. #define even(nr) (odd(nr) ? nr + 1 : nr)
  47. typedef char BOOL;
  48. #define FALSE 0
  49. #define TRUE 1
  50. #define READ 0
  51. #define APPEND 2
  52. #define CREATE 1
  53. #define MEMBER struct ar_hdr
  54. #define NIL_PTR ((char *) 0)
  55. #define NIL_MEM ((MEMBER *) 0)
  56. #define NIL_LONG ((long *) 0)
  57. #define IO_SIZE (10 * 1024)
  58. #define equal(str1, str2) (!strncmp((str1), (str2), 14))
  59. #ifndef S_ISDIR
  60. #define S_ISDIR(m) (m & S_IFDIR) /* is a directory */
  61. #endif
  62. /* Use Posix names if old-fashioned names are not defined. */
  63. #ifndef S_IREAD
  64. #define S_IREAD S_IRUSR
  65. #endif
  66. #ifndef S_IWRITE
  67. #define S_IWRITE S_IWUSR
  68. #endif
  69. #ifndef S_IEXEC
  70. #define S_IEXEC S_IXUSR
  71. #endif
  72. BOOL verbose;
  73. BOOL app_fl;
  74. BOOL ex_fl;
  75. BOOL show_fl;
  76. BOOL pr_fl;
  77. BOOL u_fl;
  78. BOOL rep_fl;
  79. BOOL del_fl;
  80. BOOL nocr_fl;
  81. BOOL local_fl;
  82. #ifdef DISTRIBUTION
  83. BOOL distr_fl;
  84. long distr_time;
  85. #endif
  86. int ar_fd;
  87. char io_buffer[IO_SIZE];
  88. char *progname;
  89. char temp_buf[32];
  90. char *temp_arch = &temp_buf[0];
  91. extern char *mktemp();
  92. extern char *ctime();
  93. usage()
  94. {
  95. error(TRUE, "usage: %s [qdprtxl][vlc] archive [file] ...\n",
  96. progname
  97. );
  98. }
  99. /*VARARGS2*/
  100. error(quit, str1, str2, str3, str4)
  101. BOOL quit;
  102. char *str1, *str2, *str3, *str4;
  103. {
  104. char errbuf[256];
  105. sprint(errbuf, str1, str2, str3, str4);
  106. write(2, errbuf, strlen(errbuf));
  107. if (quit) {
  108. unlink(temp_arch);
  109. _exit(1);
  110. }
  111. }
  112. char *basename(path)
  113. char *path;
  114. {
  115. register char *ptr = path;
  116. register char *last = NIL_PTR;
  117. while (*ptr != '\0') {
  118. if (*ptr == '/')
  119. last = ptr;
  120. ptr++;
  121. }
  122. if (last == NIL_PTR)
  123. return path;
  124. if (*(last + 1) == '\0') {
  125. *last = '\0';
  126. return basename(path);
  127. }
  128. return last + 1;
  129. }
  130. extern unsigned int rd_unsigned2();
  131. open_archive(name, mode)
  132. register char *name;
  133. register int mode;
  134. {
  135. unsigned short magic = 0;
  136. int fd;
  137. if (mode == CREATE) {
  138. if ((fd = creat(name, 0666)) < 0)
  139. error(TRUE, "cannot creat %s\n", name);
  140. magic = MAGIC_NUMBER;
  141. wr_int2(fd, magic);
  142. return fd;
  143. }
  144. if ((fd = open(name, mode)) < 0) {
  145. if (mode == APPEND) {
  146. close(open_archive(name, CREATE));
  147. if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name);
  148. return open_archive(name, APPEND);
  149. }
  150. error(TRUE, "cannot open %s\n", name);
  151. }
  152. lseek(fd, 0L, 0);
  153. magic = rd_unsigned2(fd);
  154. if (magic != AALMAG && magic != ARMAG)
  155. error(TRUE, "%s is not in ar format\n", name);
  156. return fd;
  157. }
  158. void
  159. catch()
  160. {
  161. unlink(temp_arch);
  162. _exit (2);
  163. }
  164. main(argc, argv)
  165. int argc;
  166. char *argv[];
  167. {
  168. register char *ptr;
  169. int needs_arg = 0;
  170. progname = argv[0];
  171. if (argc < 3)
  172. usage();
  173. for (ptr = argv[1]; *ptr; ptr++) {
  174. switch (*ptr) {
  175. case 't' :
  176. show_fl = TRUE;
  177. break;
  178. case 'v' :
  179. verbose = TRUE;
  180. break;
  181. case 'x' :
  182. ex_fl = TRUE;
  183. break;
  184. case 'q' :
  185. needs_arg = 1;
  186. app_fl = TRUE;
  187. break;
  188. case 'c' :
  189. nocr_fl = TRUE;
  190. break;
  191. case 'u':
  192. u_fl = TRUE;
  193. break;
  194. case 'p' :
  195. needs_arg = 1;
  196. pr_fl = TRUE;
  197. break;
  198. case 'd' :
  199. needs_arg = 1;
  200. del_fl = TRUE;
  201. break;
  202. case 'r' :
  203. needs_arg = 1;
  204. rep_fl = TRUE;
  205. break;
  206. case 'l' :
  207. local_fl = TRUE;
  208. break;
  209. #ifdef DISTRIBUTION
  210. case 'D' :
  211. distr_fl = TRUE;
  212. break;
  213. #endif
  214. default :
  215. usage();
  216. }
  217. }
  218. if (needs_arg && argc <= 3)
  219. usage();
  220. #ifdef DISTRIBUTION
  221. if (distr_fl) {
  222. static struct stat statbuf;
  223. stat(progname, &statbuf);
  224. distr_time = statbuf.st_mtime;
  225. }
  226. #endif
  227. if (local_fl) strcpy(temp_arch, "ar.XXXXXX");
  228. else strcpy(temp_arch, "/tmp/ar.XXXXXX");
  229. if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1)
  230. usage();
  231. if (u_fl && ! rep_fl)
  232. usage();
  233. if (rep_fl || del_fl
  234. #ifdef AAL
  235. || app_fl
  236. #endif
  237. ) {
  238. mktemp(temp_arch);
  239. }
  240. #ifdef AAL
  241. tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib));
  242. tstrtab = malloc(4096);
  243. if (!tab || !tstrtab) error(TRUE,"Out of core\n");
  244. tabsz = 512;
  245. strtabsz = 4096;
  246. #endif
  247. signal(SIGINT, catch);
  248. get(argc, argv);
  249. return 0;
  250. }
  251. MEMBER *
  252. get_member()
  253. {
  254. static MEMBER member;
  255. again:
  256. if (rd_arhdr(ar_fd, &member) == 0)
  257. return NIL_MEM;
  258. if (member.ar_size < 0) {
  259. error(TRUE, "archive has member with negative size\n");
  260. }
  261. if (equal(SYMDEF, member.ar_name)) {
  262. lseek(ar_fd, member.ar_size, 1);
  263. goto again;
  264. }
  265. return &member;
  266. }
  267. char *get_mode();
  268. get(argc, argv)
  269. int argc;
  270. register char *argv[];
  271. {
  272. register MEMBER *member;
  273. int i = 0;
  274. int temp_fd, read_chars;
  275. ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND);
  276. if (rep_fl || del_fl
  277. #ifdef AAL
  278. || app_fl
  279. #endif
  280. )
  281. temp_fd = open_archive(temp_arch, CREATE);
  282. while ((member = get_member()) != NIL_MEM) {
  283. if (argc > 3) {
  284. for (i = 3; i < argc; i++) {
  285. if (equal(basename(argv[i]), member->ar_name))
  286. break;
  287. }
  288. if (i == argc || app_fl) {
  289. if (rep_fl || del_fl
  290. #ifdef AAL
  291. || app_fl
  292. #endif
  293. ) {
  294. #ifdef AAL
  295. if (i != argc) {
  296. print("%s: already in archive\n", argv[i]);
  297. argv[i] = "";
  298. }
  299. #endif
  300. wr_arhdr(temp_fd, member);
  301. copy_member(member, ar_fd, temp_fd, 0);
  302. }
  303. else {
  304. #ifndef AAL
  305. if (app_fl && i != argc) {
  306. print("%s: already in archive\n", argv[i]);
  307. argv[i] = "";
  308. }
  309. #endif
  310. lseek(ar_fd, even(member->ar_size),1);
  311. }
  312. continue;
  313. }
  314. }
  315. if (ex_fl || pr_fl)
  316. extract(member);
  317. else {
  318. if (rep_fl)
  319. add(argv[i], temp_fd, "r - %s\n");
  320. else if (show_fl) {
  321. char buf[sizeof(member->ar_name) + 2];
  322. register char *p = buf, *q = member->ar_name;
  323. while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) {
  324. *p++ = *q++;
  325. }
  326. *p++ = '\n';
  327. *p = '\0';
  328. if (verbose) {
  329. char *mode = get_mode(member->ar_mode);
  330. char *date = ctime(&(member->ar_date));
  331. *(date + 16) = '\0';
  332. *(date + 24) = '\0';
  333. print("%s%3u/%u%7ld %s %s %s",
  334. mode,
  335. (unsigned) (member->ar_uid & 0377),
  336. (unsigned) (member->ar_gid & 0377),
  337. member->ar_size,
  338. date+4,
  339. date+20,
  340. buf);
  341. }
  342. else print(buf);
  343. }
  344. else if (del_fl)
  345. show("d - %s\n", member->ar_name);
  346. lseek(ar_fd, even(member->ar_size), 1);
  347. }
  348. argv[i] = "";
  349. }
  350. if (argc > 3) {
  351. for (i = 3; i < argc; i++)
  352. if (argv[i][0] != '\0') {
  353. #ifndef AAL
  354. if (app_fl)
  355. add(argv[i], ar_fd, "a - %s\n");
  356. else
  357. #endif
  358. if (rep_fl
  359. #ifdef AAL
  360. || app_fl
  361. #endif
  362. )
  363. add(argv[i], temp_fd, "a - %s\n");
  364. else {
  365. print("%s: not found\n", argv[i]);
  366. }
  367. }
  368. }
  369. if (rep_fl || del_fl
  370. #ifdef AAL
  371. || app_fl
  372. #endif
  373. ) {
  374. signal(SIGINT, SIG_IGN);
  375. close(ar_fd);
  376. close(temp_fd);
  377. ar_fd = open_archive(argv[2], CREATE);
  378. temp_fd = open_archive(temp_arch, APPEND);
  379. #ifdef AAL
  380. write_symdef();
  381. #endif
  382. while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0)
  383. mwrite(ar_fd, io_buffer, read_chars);
  384. close(temp_fd);
  385. unlink(temp_arch);
  386. }
  387. close(ar_fd);
  388. }
  389. add(name, fd, mess)
  390. char *name;
  391. int fd;
  392. char *mess;
  393. {
  394. static MEMBER member;
  395. register int read_chars;
  396. struct stat status;
  397. int src_fd;
  398. if (stat(name, &status) < 0) {
  399. error(FALSE, "cannot find %s\n", name);
  400. return;
  401. }
  402. else if (S_ISDIR(status.st_mode)) {
  403. error(FALSE, "%s is a directory (ignored)\n", name);
  404. return;
  405. }
  406. else if (u_fl && status.st_mtime <= member.ar_date) {
  407. wr_arhdr(fd, member);
  408. copy_member(member, ar_fd, fd, 0);
  409. return;
  410. }
  411. else if ((src_fd = open(name, 0)) < 0) {
  412. error(FALSE, "cannot open %s\n", name);
  413. return;
  414. }
  415. strncpy (member.ar_name, basename (name), sizeof(member.ar_name));
  416. member.ar_uid = status.st_uid;
  417. member.ar_gid = status.st_gid;
  418. member.ar_mode = status.st_mode;
  419. member.ar_date = status.st_mtime;
  420. member.ar_size = status.st_size;
  421. #ifdef DISTRIBUTION
  422. if (distr_fl) {
  423. member.ar_uid = 2;
  424. member.ar_gid = 2;
  425. member.ar_mode = 0644;
  426. member.ar_date = distr_time;
  427. }
  428. #endif
  429. wr_arhdr(fd, &member);
  430. #ifdef AAL
  431. do_object(src_fd, member.ar_size);
  432. lseek(src_fd, 0L, 0);
  433. offset += AR_TOTAL + even(member.ar_size);
  434. #endif
  435. while (status.st_size > 0) {
  436. int x = IO_SIZE;
  437. read_chars = x;
  438. if (status.st_size < x) {
  439. x = status.st_size;
  440. read_chars = x;
  441. status.st_size = 0;
  442. x = even(x);
  443. }
  444. else status.st_size -= x;
  445. if (read(src_fd, io_buffer, read_chars) != read_chars) {
  446. error(FALSE,"%s seems to shrink\n", name);
  447. break;
  448. }
  449. mwrite(fd, io_buffer, x);
  450. }
  451. if (verbose)
  452. show(mess, member.ar_name);
  453. close(src_fd);
  454. }
  455. extract(member)
  456. register MEMBER *member;
  457. {
  458. int fd = 1;
  459. char buf[sizeof(member->ar_name) + 1];
  460. strncpy(buf, member->ar_name, sizeof(member->ar_name));
  461. buf[sizeof(member->ar_name)] = 0;
  462. if (pr_fl == FALSE && (fd = creat(buf, 0666)) < 0) {
  463. error(FALSE, "cannot create %s\n", buf);
  464. fd = -1;
  465. }
  466. if (verbose) {
  467. if (pr_fl == FALSE) show("x - %s\n", buf);
  468. else show("\n<%s>\n\n", buf);
  469. }
  470. copy_member(member, ar_fd, fd, 1);
  471. if (fd >= 0 && fd != 1)
  472. close(fd);
  473. if (pr_fl == FALSE) chmod(buf, member->ar_mode);
  474. }
  475. copy_member(member, from, to, extracting)
  476. register MEMBER *member;
  477. int from, to;
  478. {
  479. register int rest;
  480. long mem_size = member->ar_size;
  481. BOOL is_odd = odd(mem_size) ? TRUE : FALSE;
  482. #ifdef AAL
  483. if (! extracting) {
  484. long pos = lseek(from, 0L, 1);
  485. do_object(from, mem_size);
  486. offset += AR_TOTAL + even(mem_size);
  487. lseek(from, pos, 0);
  488. }
  489. #endif
  490. do {
  491. rest = mem_size > (long) IO_SIZE ? IO_SIZE : (int) mem_size;
  492. if (read(from, io_buffer, rest) != rest) {
  493. char buf[sizeof(member->ar_name) + 1];
  494. strncpy(buf, member->ar_name, sizeof(member->ar_name));
  495. buf[sizeof(member->ar_name)] = 0;
  496. error(TRUE, "read error on %s\n", buf);
  497. }
  498. if (to >= 0) mwrite(to, io_buffer, rest);
  499. mem_size -= (long) rest;
  500. } while (mem_size > 0L);
  501. if (is_odd) {
  502. lseek(from, 1L, 1);
  503. if (to >= 0 && ! extracting)
  504. lseek(to, 1L, 1);
  505. }
  506. }
  507. char *
  508. get_mode(mode)
  509. register int mode;
  510. {
  511. static char mode_buf[11];
  512. register int tmp = mode;
  513. int i;
  514. mode_buf[9] = ' ';
  515. for (i = 0; i < 3; i++) {
  516. mode_buf[i * 3] = (tmp & S_IREAD) ? 'r' : '-';
  517. mode_buf[i * 3 + 1] = (tmp & S_IWRITE) ? 'w' : '-';
  518. mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-';
  519. tmp <<= 3;
  520. }
  521. if (mode & S_ISUID)
  522. mode_buf[2] = 's';
  523. if (mode & S_ISGID)
  524. mode_buf[5] = 's';
  525. return mode_buf;
  526. }
  527. wr_fatal()
  528. {
  529. error(TRUE, "write error\n");
  530. }
  531. rd_fatal()
  532. {
  533. error(TRUE, "read error\n");
  534. }
  535. mwrite(fd, address, bytes)
  536. int fd;
  537. register char *address;
  538. register int bytes;
  539. {
  540. if (write(fd, address, bytes) != bytes)
  541. error(TRUE, "write error\n");
  542. }
  543. show(s, name)
  544. char *s, *name;
  545. {
  546. MEMBER x;
  547. char buf[sizeof(x.ar_name)+1];
  548. register char *p = buf, *q = name;
  549. while (q <= &name[sizeof(x.ar_name)-1] && *q) *p++ = *q++;
  550. *p++ = '\0';
  551. print(s, buf);
  552. }
  553. #ifdef AAL
  554. /*
  555. * Write out the ranlib table: first 4 bytes telling how many ranlib structs
  556. * there are, followed by the ranlib structs,
  557. * then 4 bytes giving the size of the string table, followed by the string
  558. * table itself.
  559. */
  560. write_symdef()
  561. {
  562. register struct ranlib *ran;
  563. register int i;
  564. register long delta;
  565. MEMBER arbuf;
  566. if (! tnum) return;
  567. if (odd(tssiz))
  568. tstrtab[tssiz++] = '\0';
  569. for (i = 0; i < sizeof(arbuf.ar_name); i++)
  570. arbuf.ar_name[i] = '\0';
  571. strcpy(arbuf.ar_name, SYMDEF);
  572. arbuf.ar_size = 4 + 2 * 4 * (long)tnum + 4 + (long)tssiz;
  573. time(&arbuf.ar_date);
  574. arbuf.ar_uid = getuid();
  575. arbuf.ar_gid = getgid();
  576. arbuf.ar_mode = 0444;
  577. #ifdef DISTRIBUTION
  578. if (distr_fl) {
  579. arbuf.ar_uid = 2;
  580. arbuf.ar_gid = 2;
  581. arbuf.ar_date = distr_time;
  582. }
  583. #endif
  584. wr_arhdr(ar_fd,&arbuf);
  585. wr_long(ar_fd, (long) tnum);
  586. /*
  587. * Account for the space occupied by the magic number
  588. * and the ranlib table.
  589. */
  590. delta = 2 + AR_TOTAL + arbuf.ar_size;
  591. for (ran = tab; ran < &tab[tnum]; ran++) {
  592. ran->ran_pos += delta;
  593. }
  594. wr_ranlib(ar_fd, tab, (long) tnum);
  595. wr_long(ar_fd, (long) tssiz);
  596. wr_bytes(ar_fd, tstrtab, (long) tssiz);
  597. }
  598. /*
  599. * Return whether the bytes in `buf' form a good object header.
  600. * The header is put in `headp'.
  601. */
  602. int
  603. is_outhead(headp)
  604. register struct outhead *headp;
  605. {
  606. return !BADMAGIC(*headp) && headp->oh_nname != 0;
  607. }
  608. do_object(f, size)
  609. long size;
  610. {
  611. struct outhead headbuf;
  612. if (size < SZ_HEAD) {
  613. /* It can't be an object file. */
  614. return;
  615. }
  616. /*
  617. * Read a header to see if it is an object file.
  618. */
  619. if (! rd_fdopen(f)) {
  620. rd_fatal();
  621. }
  622. rd_ohead(&headbuf);
  623. if (!is_outhead(&headbuf)) {
  624. return;
  625. }
  626. do_names(&headbuf);
  627. }
  628. /*
  629. * First skip the names and read in the string table, then seek back to the
  630. * name table and read and write the names one by one. Update the ranlib table
  631. * accordingly.
  632. */
  633. do_names(headp)
  634. struct outhead *headp;
  635. {
  636. register char *strings;
  637. register int nnames = headp->oh_nname;
  638. #define NNAMES 100
  639. struct outname namebuf[NNAMES];
  640. long xxx = OFF_CHAR(*headp);
  641. if ( headp->oh_nchar != (unsigned int)headp->oh_nchar ||
  642. (strings = malloc((unsigned int)headp->oh_nchar)) == (char *)0
  643. ) {
  644. error(TRUE, "string table too big\n");
  645. }
  646. rd_string(strings, headp->oh_nchar);
  647. while (nnames) {
  648. int i = nnames >= NNAMES ? NNAMES : nnames;
  649. register struct outname *p = namebuf;
  650. nnames -= i;
  651. rd_name(namebuf, i);
  652. while (i--) {
  653. long off = p->on_foff - xxx;
  654. if (p->on_foff == (long)0) {
  655. p++;
  656. continue; /* An unrecognizable name. */
  657. }
  658. p->on_mptr = strings + off;
  659. /*
  660. * Only enter names that are exported and are really
  661. * defined. Also enter common names. Note, that
  662. * this might cause problems when the name is really
  663. * defined in a later file, with a value != 0.
  664. * However, this problem also exists on the Unix
  665. * ranlib archives.
  666. */
  667. if ( (p->on_type & S_EXT) &&
  668. (p->on_type & S_TYP) != S_UND
  669. )
  670. enter_name(p);
  671. p++;
  672. }
  673. }
  674. free(strings);
  675. }
  676. enter_name(namep)
  677. struct outname *namep;
  678. {
  679. register char *cp;
  680. if (tnum >= tabsz) {
  681. tab = (struct ranlib *)
  682. realloc((char *) tab, (tabsz += 512) * sizeof(struct ranlib));
  683. if (! tab) error(TRUE, "Out of core\n");
  684. }
  685. tab[tnum].ran_off = tssiz;
  686. tab[tnum].ran_pos = offset;
  687. for (cp = namep->on_mptr;; cp++) {
  688. if (tssiz >= strtabsz) {
  689. tstrtab = realloc(tstrtab, (strtabsz += 4096));
  690. if (! tstrtab) error(TRUE, "string table overflow\n");
  691. }
  692. tstrtab[tssiz++] = *cp;
  693. if (!*cp) break;
  694. }
  695. tnum++;
  696. }
  697. #endif /* AAL */