BSD 4_3 release
[unix-history] / usr / src / usr.bin / ranlib.c
index 4f5ed67..ec3efb7 100644 (file)
@@ -1,11 +1,25 @@
-static char sccsid[] = "@(#)ranlib.c 4.3 4/26/81";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)ranlib.c   5.3 (Berkeley) 1/22/86";
+#endif not lint
+
 /*
  * ranlib - create table of contents for archive; string table version
  */
 #include <sys/types.h>
 #include <ar.h>
 #include <ranlib.h>
 /*
  * 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>
 
 #include <a.out.h>
 #include <stdio.h>
 
@@ -16,23 +30,51 @@ struct      exec    exp;
 FILE   *fi, *fo;
 long   off, oldoff;
 long   atol(), ftell();
 FILE   *fi, *fo;
 long   off, oldoff;
 long   atol(), ftell();
-#define TABSZ  5000
-struct ranlib tab[TABSZ];
+#define TABSZ  3000
 int    tnum;
 int    tnum;
-#define        STRTABSZ        75000
-char   tstrtab[STRTABSZ];
+#define        STRTABSZ        30000
 int    tssiz;
 char   *strtab;
 int    ssiz;
 int    new;
 char   tempnm[] = "__.SYMDEF";
 char   firstname[17];
 int    tssiz;
 char   *strtab;
 int    ssiz;
 int    new;
 char   tempnm[] = "__.SYMDEF";
 char   firstname[17];
+void   stash();
+char *malloc(), *calloc();
+
+/*
+ * table segment definitions
+ */
+char   *segalloc();
+void   segclean();
+struct tabsegment {
+       struct tabsegment       *pnext;
+       unsigned                nelem;
+       struct ranlib           tab[TABSZ];
+} tabbase, *ptabseg;
+struct strsegment {
+       struct strsegment       *pnext;
+       unsigned                nelem;
+       char                    stab[STRTABSZ];
+} strbase, *pstrseg;
 
 main(argc, argv)
 char **argv;
 {
        char cmdbuf[BUFSIZ];
 
 main(argc, argv)
 char **argv;
 {
        char cmdbuf[BUFSIZ];
-       char magbuf[SARMAG+1];
+       /* magbuf must be an int array so it is aligned on an int-ish
+          boundary, so that we may access its first word as an int! */
+       int magbuf[(SARMAG+sizeof(int))/sizeof(int)];
+       register int just_touch = 0;
+       register struct tabsegment *ptab;
+       register struct strsegment *pstr;
+
+       /* check for the "-t" flag" */
+       if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+               just_touch++;
+               argc--;
+               argv++;
+       }
 
        --argc;
        while(argc--) {
 
        --argc;
        while(argc--) {
@@ -42,17 +84,37 @@ char **argv;
                        continue;
                }
                off = SARMAG;
                        continue;
                }
                off = SARMAG;
-               fread(magbuf, 1, SARMAG, fi);
-               if (strncmp(magbuf, ARMAG, SARMAG)) {
-                       if (*(int *)magbuf == OARMAG)
+               fread((char *)magbuf, 1, SARMAG, fi);
+               if (strncmp((char *)magbuf, ARMAG, SARMAG)) {
+                       if (magbuf[0] == OARMAG)
                                fprintf(stderr, "old format ");
                        else
                                fprintf(stderr, "not an ");
                        fprintf(stderr, "archive: %s\n", *argv);
                        continue;
                }
                                fprintf(stderr, "old format ");
                        else
                                fprintf(stderr, "not an ");
                        fprintf(stderr, "archive: %s\n", *argv);
                        continue;
                }
+               if (just_touch) {
+                       register int    len;
+
+                       fseek(fi, (long) SARMAG, 0);
+                       if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) {
+                               fprintf(stderr, "malformed archive: %s\n",
+                                       *argv);
+                               continue;
+                       }
+                       len = strlen(tempnm);
+                       if (bcmp(cmdbuf, tempnm, len) != 0 ||
+                           cmdbuf[len] != ' ') {
+                               fprintf(stderr, "no symbol table: %s\n", *argv);
+                               continue;
+                       }
+                       fclose(fi);
+                       fixdate(*argv);
+                       continue;
+               }
                fseek(fi, 0L, 0);
                fseek(fi, 0L, 0);
-               new = tnum = 0;
+               new = tssiz = tnum = 0;
+               segclean();
                if (nextel(fi) == 0) {
                        fclose(fi);
                        continue;
                if (nextel(fi) == 0) {
                        fclose(fi);
                        continue;
@@ -65,17 +127,24 @@ char **argv;
                        fread((char *)&exp, 1, sizeof(struct exec), fi);
                        if (N_BADMAG(exp))
                                continue;
                        fread((char *)&exp, 1, sizeof(struct exec), fi);
                        if (N_BADMAG(exp))
                                continue;
+                       if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name)))
+                               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) {
                        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);
+                               fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name);
+                               continue;
                        }
                        fseek(fi, o, 1);
                        fread((char *)&ssiz, 1, sizeof (ssiz), fi);
                        }
                        fseek(fi, o, 1);
                        fread((char *)&ssiz, 1, sizeof (ssiz), fi);
+                       if (ssiz < sizeof ssiz){
+                               /* sanity check */
+                               fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name);
+                               continue;
+                       }
                        strtab = (char *)calloc(1, ssiz);
                        if (strtab == 0) {
                                fprintf(stderr, "ranlib: ran out of memory\n");
                        strtab = (char *)calloc(1, ssiz);
                        if (strtab == 0) {
                                fprintf(stderr, "ranlib: ran out of memory\n");
@@ -103,6 +172,7 @@ char **argv;
                                        continue;
                                }
                        }
                                        continue;
                                }
                        }
+                       free(strtab);
                } while(nextel(fi));
                new = fixsize();
                fclose(fi);
                } while(nextel(fi));
                new = fixsize();
                fclose(fi);
@@ -114,9 +184,19 @@ char **argv;
                tnum *= sizeof (struct ranlib);
                fwrite(&tnum, 1, sizeof (tnum), fo);
                tnum /= sizeof (struct ranlib);
                tnum *= sizeof (struct ranlib);
                fwrite(&tnum, 1, sizeof (tnum), fo);
                tnum /= sizeof (struct ranlib);
-               fwrite((char *)tab, tnum, sizeof(struct ranlib), fo);
+               ptab = &tabbase;
+               do {
+                       fwrite((char *)ptab->tab, ptab->nelem,
+                           sizeof(struct ranlib), fo);
+               } while (ptab = ptab->pnext);
                fwrite(&tssiz, 1, sizeof (tssiz), fo);
                fwrite(&tssiz, 1, sizeof (tssiz), fo);
-               fwrite(tstrtab, tssiz, 1, fo);
+               pstr = &strbase;
+               do {
+                       fwrite(pstr->stab, pstr->nelem, 1, fo);
+                       tssiz -= pstr->nelem;
+               } while (pstr = pstr->pnext);
+               /* pad with nulls */
+               while (tssiz--) putc('\0', fo);
                fclose(fo);
                if(new)
                        sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
                fclose(fo);
                if(new)
                        sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
@@ -152,30 +232,114 @@ FILE *af;
        return(1);
 }
 
        return(1);
 }
 
+void
 stash(s)
        struct nlist *s;
 {
 stash(s)
        struct nlist *s;
 {
-       int i;
        register char *cp;
        register char *cp;
+       register char *strtab;
+       register strsiz;
+       register struct ranlib *tab;
+       register tabsiz;
 
 
-       if(tnum >= TABSZ) {
-               fprintf(stderr, "ranlib: symbol table overflow\n");
-               exit(1);
+       if (ptabseg->nelem >= TABSZ) {
+               /* allocate a new symbol table segment */
+               ptabseg = ptabseg->pnext =
+                   (struct tabsegment *) segalloc(sizeof(struct tabsegment));
+               ptabseg->pnext = NULL;
+               ptabseg->nelem = 0;
        }
        }
-       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);
+       tabsiz = ptabseg->nelem;
+       tab = ptabseg->tab;
+
+       if (pstrseg->nelem >= STRTABSZ) {
+               /* allocate a new string table segment */
+               pstrseg = pstrseg->pnext =
+                   (struct strsegment *) segalloc(sizeof(struct strsegment));
+               pstrseg->pnext = NULL;
+               pstrseg->nelem = 0;
+       }
+       strsiz = pstrseg->nelem;
+       strtab = pstrseg->stab;
+
+       tab[tabsiz].ran_un.ran_strx = tssiz;
+       tab[tabsiz].ran_off = oldoff;
+redo:
+       for (cp = s->n_un.n_name; strtab[strsiz++] = *cp++;)
+               if (strsiz >= STRTABSZ) {
+                       /* allocate a new string table segment */
+                       pstrseg = pstrseg->pnext =
+                           (struct strsegment *) segalloc(sizeof(struct strsegment));
+                       pstrseg->pnext = NULL;
+                       strsiz = pstrseg->nelem = 0;
+                       strtab = pstrseg->stab;
+                       goto redo;
                }
                }
+
+       tssiz += strsiz - pstrseg->nelem; /* length of the string */
+       pstrseg->nelem = strsiz;
        tnum++;
        tnum++;
+       ptabseg->nelem++;
+}
+
+/* allocate a zero filled segment of size bytes */
+char *
+segalloc(size)
+unsigned size;
+{
+       char *pseg = NULL;
+
+       pseg = malloc(size);
+       if (pseg == NULL) {
+               fprintf(stderr, "ranlib: ran out of memeory\n");
+               exit(1);
+       }
+       return(pseg);
+}
+
+/* free segments */
+void
+segclean()
+{
+       register struct tabsegment *ptab;
+       register struct strsegment *pstr;
+
+       /*
+        * symbol table
+        *
+        * The first entry is static.
+        */
+       ptabseg = &tabbase;
+       ptab = ptabseg->pnext;
+       while (ptabseg = ptab) {
+               ptab = ptabseg->pnext;
+               free((char *)ptabseg);
+       }
+       ptabseg = &tabbase;
+       ptabseg->pnext = NULL;
+       ptabseg->nelem = 0;
+
+       /*
+        * string table
+        *
+        * The first entry is static.
+        */
+       pstrseg = &strbase;
+       pstr = pstrseg->pnext;
+       while (pstrseg = pstr) {
+               pstr = pstrseg->pnext;
+               free((char *)pstrseg);
+       }
+       pstrseg = &strbase;
+       pstrseg->pnext = NULL;
+       pstrseg->nelem = 0;
 }
 
 fixsize()
 {
        int i;
        off_t offdelta;
 }
 
 fixsize()
 {
        int i;
        off_t offdelta;
+       register struct tabsegment *ptab;
 
        if (tssiz&1)
                tssiz++;
 
        if (tssiz&1)
                tssiz++;
@@ -190,8 +354,11 @@ fixsize()
                new = 1;
                strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
        }
                new = 1;
                strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
        }
-       for(i=0; i<tnum; i++)
-               tab[i].ran_off += offdelta;
+       ptab = &tabbase;
+       do {
+               for (i = 0; i < ptab->nelem; i++)
+                       ptab->tab[i].ran_off += offdelta;
+       } while (ptab = ptab->pnext);
        return(new);
 }
 
        return(new);
 }