archiver.c 15 KB

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