archiver.c 15 KB

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