BSD 4_1_snap release
[unix-history] / usr / src / cmd / ranlib.c
index a0b6e91..4f5ed67 100644 (file)
@@ -1,47 +1,60 @@
-#include       <ar.h>
-#include       <a.out.h>
-#include       <stdio.h>
-#define        MAGIC   exp.a_magic
-#define        BADMAG  MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2  \
-               && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4
-struct ar_hdr  arp;
+static char sccsid[] = "@(#)ranlib.c 4.3 4/26/81";
+/*
+ * ranlib - create table of contents for archive; string table version
+ */
+#include <sys/types.h>
+#include <ar.h>
+#include <ranlib.h>
+#include <pagsiz.h>
+#include <a.out.h>
+#include <stdio.h>
+
+struct ar_hdr  archdr;
+#define        OARMAG 0177545
+long   arsize;
 struct exec    exp;
 FILE   *fi, *fo;
 long   off, oldoff;
 struct exec    exp;
 FILE   *fi, *fo;
 long   off, oldoff;
-long   ftell();
-#define TABSZ  700
-struct tab
-{      char cname[8];
-       long cloc;
-} tab[TABSZ];
-int tnum;
-int new;
+long   atol(), ftell();
+#define TABSZ  5000
+struct ranlib tab[TABSZ];
+int    tnum;
+#define        STRTABSZ        75000
+char   tstrtab[STRTABSZ];
+int    tssiz;
+char   *strtab;
+int    ssiz;
+int    new;
 char   tempnm[] = "__.SYMDEF";
 char   firstname[17];
 char   tempnm[] = "__.SYMDEF";
 char   firstname[17];
-long   offdelta;
 
 main(argc, argv)
 char **argv;
 {
 
 main(argc, argv)
 char **argv;
 {
-       char buf[256];
+       char cmdbuf[BUFSIZ];
+       char magbuf[SARMAG+1];
 
        --argc;
        while(argc--) {
                fi = fopen(*++argv,"r");
                if (fi == NULL) {
 
        --argc;
        while(argc--) {
                fi = fopen(*++argv,"r");
                if (fi == NULL) {
-                       fprintf(stderr, "nm: cannot open %s\n", *argv);
+                       fprintf(stderr, "ranlib: cannot open %s\n", *argv);
                        continue;
                }
                        continue;
                }
-               off = sizeof(exp.a_magic);
-               fread((char *)&exp, 1, sizeof(MAGIC), fi);      /* get magic no. */
-               if (MAGIC != ARMAG)
-               {       fprintf(stderr, "not archive: %s\n", *argv);
+               off = SARMAG;
+               fread(magbuf, 1, SARMAG, fi);
+               if (strncmp(magbuf, ARMAG, SARMAG)) {
+                       if (*(int *)magbuf == OARMAG)
+                               fprintf(stderr, "old format ");
+                       else
+                               fprintf(stderr, "not an ");
+                       fprintf(stderr, "archive: %s\n", *argv);
                        continue;
                }
                fseek(fi, 0L, 0);
                new = tnum = 0;
                        continue;
                }
                fseek(fi, 0L, 0);
                new = tnum = 0;
-               if(nextel(fi) == 0)
-               {       fclose(fi);
+               if (nextel(fi) == 0) {
+                       fclose(fi);
                        continue;
                }
                do {
                        continue;
                }
                do {
@@ -50,24 +63,39 @@ char **argv;
                        struct nlist sym;
 
                        fread((char *)&exp, 1, sizeof(struct exec), fi);
                        struct nlist sym;
 
                        fread((char *)&exp, 1, sizeof(struct exec), fi);
-                       if (BADMAG)             /* archive element not in  */
-                               continue;       /* proper format - skip it */
-                       o = (long)exp.a_text + exp.a_data;
-                       if ((exp.a_flag & 01) == 0)
-                               o *= 2;
-                       fseek(fi, o, 1);
-                       n = exp.a_syms / sizeof(struct nlist);
-                       if (n == 0) {
-                               fprintf(stderr, "nm: %s-- no name list\n", arp.ar_name);
+                       if (N_BADMAG(exp))
                                continue;
                                continue;
+                       if (exp.a_syms == 0) {
+                               fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name);
+                               continue;
+                       }
+                       o = N_STROFF(exp) - sizeof (struct exec);
+                       if (ftell(fi)+o+sizeof(ssiz) >= off) {
+                               fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name);
+                               exit(1);
                        }
                        }
+                       fseek(fi, o, 1);
+                       fread((char *)&ssiz, 1, sizeof (ssiz), fi);
+                       strtab = (char *)calloc(1, ssiz);
+                       if (strtab == 0) {
+                               fprintf(stderr, "ranlib: ran out of memory\n");
+                               exit(1);
+                       }
+                       fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi);
+                       fseek(fi, -(exp.a_syms+ssiz), 1);
+                       n = exp.a_syms / sizeof(struct nlist);
                        while (--n >= 0) {
                                fread((char *)&sym, 1, sizeof(sym), fi);
                        while (--n >= 0) {
                                fread((char *)&sym, 1, sizeof(sym), fi);
+                               if (sym.n_un.n_strx == 0)
+                                       continue;
+                               sym.n_un.n_name = strtab + sym.n_un.n_strx;
                                if ((sym.n_type&N_EXT)==0)
                                        continue;
                                switch (sym.n_type&N_TYPE) {
 
                                case N_UNDF:
                                if ((sym.n_type&N_EXT)==0)
                                        continue;
                                switch (sym.n_type&N_TYPE) {
 
                                case N_UNDF:
+                                       if (sym.n_value!=0)
+                                               stash(&sym);
                                        continue;
 
                                default:
                                        continue;
 
                                default:
@@ -79,18 +107,25 @@ char **argv;
                new = fixsize();
                fclose(fi);
                fo = fopen(tempnm, "w");
                new = fixsize();
                fclose(fi);
                fo = fopen(tempnm, "w");
-               if(fo == NULL)
-               {       fprintf(stderr, "can't create temporary\n");
+               if(fo == NULL) {
+                       fprintf(stderr, "can't create temporary\n");
                        exit(1);
                }
                        exit(1);
                }
-               fwrite((char *)tab, tnum, sizeof(struct tab), fo);
+               tnum *= sizeof (struct ranlib);
+               fwrite(&tnum, 1, sizeof (tnum), fo);
+               tnum /= sizeof (struct ranlib);
+               fwrite((char *)tab, tnum, sizeof(struct ranlib), fo);
+               fwrite(&tssiz, 1, sizeof (tssiz), fo);
+               fwrite(tstrtab, tssiz, 1, fo);
                fclose(fo);
                if(new)
                fclose(fo);
                if(new)
-                       sprintf(buf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
-               else    sprintf(buf, "ar rl %s %s\n", *argv, tempnm);
-               if(system(buf))
-                       fprintf(stderr, "can't execute %s\n", buf);
-               else fixdate(*argv);
+                       sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
+               else
+                       sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
+               if(system(cmdbuf))
+                       fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf);
+               else
+                       fixdate(*argv);
                unlink(tempnm);
        }
        exit(0);
                unlink(tempnm);
        }
        exit(0);
@@ -100,59 +135,81 @@ nextel(af)
 FILE *af;
 {
        register r;
 FILE *af;
 {
        register r;
+       register char *cp;
 
        oldoff = off;
        fseek(af, off, 0);
 
        oldoff = off;
        fseek(af, off, 0);
-       r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af);  /* read archive header */
-       if (r <= 0)
+       r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af);
+       if (r != sizeof(struct ar_hdr))
                return(0);
                return(0);
-       if (arp.ar_size & 1)
-               ++arp.ar_size;
-       off = ftell(af) + arp.ar_size;  /* offset to next element */
+       for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++)
+               if (*cp == ' ')
+                       *cp = '\0';
+       arsize = atol(archdr.ar_size);
+       if (arsize & 1)
+               arsize++;
+       off = ftell(af) + arsize;
        return(1);
 }
 
        return(1);
 }
 
-stash(s) struct nlist *s;
-{      int i;
-       if(tnum >= TABSZ)
-       {       fprintf(stderr, "symbol table overflow\n");
+stash(s)
+       struct nlist *s;
+{
+       int i;
+       register char *cp;
+
+       if(tnum >= TABSZ) {
+               fprintf(stderr, "ranlib: symbol table overflow\n");
                exit(1);
        }
                exit(1);
        }
-       for(i=0; i<8; i++)
-               tab[tnum].cname[i] = s->n_name[i];
-       tab[tnum].cloc = oldoff;
+       tab[tnum].ran_un.ran_strx = tssiz;
+       tab[tnum].ran_off = oldoff;
+       for (cp = s->n_un.n_name; tstrtab[tssiz++] = *cp++;)
+               if (tssiz > STRTABSZ) {
+                       fprintf(stderr, "ranlib: string table overflow\n");
+                       exit(1);
+               }
        tnum++;
 }
 
 fixsize()
        tnum++;
 }
 
 fixsize()
-{      int i;
-       offdelta = tnum * sizeof(struct tab) + sizeof(arp);
-       off = sizeof(MAGIC);
+{
+       int i;
+       off_t offdelta;
+
+       if (tssiz&1)
+               tssiz++;
+       offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) +
+           sizeof (tssiz) + tssiz;
+       off = SARMAG;
        nextel(fi);
        nextel(fi);
-       if(strncmp(arp.ar_name, tempnm, 14) == 0)
-       {       new = 0;
-               offdelta -= sizeof(arp) + arp.ar_size;
-       }
-       else
-       {       new = 1;
-               strncpy(firstname, arp.ar_name, 14);
+       if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) {
+               new = 0;
+               offdelta -= sizeof(archdr) + arsize;
+       } else {
+               new = 1;
+               strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
        }
        for(i=0; i<tnum; i++)
        }
        for(i=0; i<tnum; i++)
-               tab[i].cloc += offdelta;
+               tab[i].ran_off += offdelta;
        return(new);
 }
 
 /* patch time */
        return(new);
 }
 
 /* patch time */
-fixdate(s) char *s;
-{      long timex, time();
+fixdate(s)
+       char *s;
+{
+       long time();
+       char buf[24];
        int fd;
        int fd;
+
        fd = open(s, 1);
        fd = open(s, 1);
-       if(fd < 0)
-       {       fprintf(stderr, "can't reopen %s\n", s);
+       if(fd < 0) {
+               fprintf(stderr, "ranlib: can't reopen %s\n", s);
                return;
        }
                return;
        }
-       timex = time(NULL) + 5; /* should be enough time */
-       lseek(fd, (long)sizeof(exp.a_magic) + ((char *)&arp.ar_date-(char *)&arp), 0);
-       write(fd, (char *)&timex, sizeof(timex));
+       sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5);
+       lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0);
+       write(fd, buf, sizeof(archdr.ar_date));
        close(fd);
 }
        close(fd);
 }