# 2.11BSD#431 - /usr/src/usr.bin/ranlib/build.c

##### Functions

    build             X
    sgets             X

##### Variables

    pnext             X
    rhead             X
    symcnt            X
    tsymlen           X

##### struct's

    _rlib             X

##### typedef's

    RLIB              X

       1: /*-
       2:  * Copyright (c) 1990 The Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * This code is derived from software contributed to Berkeley by
       6:  * Hugh Smith at The University of Guelph.
       7:  *
       8:  * Redistribution and use in source and binary forms, with or without
       9:  * modification, are permitted provided that the following conditions
      10:  * are met:
      11:  * 1. Redistributions of source code must retain the above copyright
      12:  *    notice, this list of conditions and the following disclaimer.
      13:  * 2. Redistributions in binary form must reproduce the above copyright
      14:  *    notice, this list of conditions and the following disclaimer in the
      15:  *    documentation and/or other materials provided with the distribution.
      16:  * 3. All advertising materials mentioning features or use of this software
      17:  *    must display the following acknowledgement:
      18:  *	This product includes software developed by the University of
      19:  *	California, Berkeley and its contributors.
      20:  * 4. Neither the name of the University nor the names of its contributors
      21:  *    may be used to endorse or promote products derived from this software
      22:  *    without specific prior written permission.
      23:  *
      24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      34:  * SUCH DAMAGE.
      35:  */
      36:
      37: #if !defined(lint) && defined(DOSCCS)
      38: static char sccsid[] = "@(#)build.c	5.3.1 (Berkeley) 5/17/93";
      39: #endif
      40:
      41: #include <sys/types.h>
      42: #include <sys/errno.h>
      43: #include <sys/stat.h>
      44: #include <fcntl.h>
      45: #include <a.out.h>
      46: #include <sys/dir.h>
      47: #include <sys/file.h>
      48: #include <ar.h>
      49: #include <ranlib.h>
      50: #include <stdio.h>
      51: #include <archive.h>
      52:
      53: extern  off_t   lseek();
      54: extern CHDR chdr;           /* converted header */
      55: extern char *archive;           /* archive name */
      56: extern char *tname;         /* temporary file "name" */
      57:
      58: typedef struct _rlib {
      59:     struct _rlib *next;     /* next structure */
      60:     off_t pos;          /* offset of defining archive file */
      61:     char *sym;          /* symbol */
      62:     int symlen;         /* strlen(sym) */
      63: } RLIB;
      64: RLIB *rhead, **pnext;
      65:
      66: FILE *fp;
      67: static void rexec(), symobj();
      68: void error(), badfmt();
      69: long symcnt;                /* symbol count */
      70: long tsymlen;               /* total string length */
      71:
      72: build()
      73: {
      74:     CF cf;
      75:     int afd, tfd;
      76:     off_t size;
      77:
      78:     afd = open_archive(O_RDWR);
      79:     fp = fdopen(afd, "r+");
      80:     tfd = tmp();
      81:
      82:     SETCF(afd, archive, tfd, tname, RPAD|WPAD);
      83:
      84:     /* Read through the archive, creating list of symbols. */
      85:     pnext = &rhead;
      86:     symcnt = tsymlen = 0;
      87:     while(get_arobj(afd)) {
      88:         if (!strcmp(chdr.name, RANLIBMAG)) {
      89:             skip_arobj(afd);
      90:             continue;
      91:         }
      92:         rexec(afd, tfd);
      93:         put_arobj(&cf, (struct stat *)NULL);
      94:     }
      95:     *pnext = NULL;
      96:
      97:     /* Create the symbol table. */
      98:     symobj();
      99:
     100:     /* Copy the saved objects into the archive. */
     101:     size = lseek(tfd, (off_t)0, L_INCR);
     102:     (void)lseek(tfd, (off_t)0, L_SET);
     103:     SETCF(tfd, tname, afd, archive, RPAD|WPAD);
     104:     copy_ar(&cf, size);
     105:     (void)ftruncate(afd, lseek(afd, (off_t)0, L_INCR));
     106:     (void)close(tfd);
     107:
     108:     /* Set the time. */
     109:     settime(afd);
     110:     close_archive(afd);
     111:     return(0);
     112: }
     113:
     114: /*
     115:  * rexec
     116:  *	Read the exec structure; ignore any files that don't look
     117:  *	exactly right.
     118:  */
     119: static void
     120: rexec(rfd, wfd)
     121:     int rfd;
     122:     int wfd;
     123: {
     124:     register RLIB *rp;
     125:     RLIB **savnext;
     126:     long nsyms;
     127:     register int nr, symlen;
     128:     char sym[512];      /* XXX - more than enough (we hope) */
     129:     struct exec ebuf;
     130:     struct nlist nl;
     131:     off_t r_off, w_off, sympos;
     132:     void *emalloc();
     133:
     134:     /* Get current offsets for original and tmp files. */
     135:     r_off = lseek(rfd, (off_t)0, L_INCR);
     136:     w_off = lseek(wfd, (off_t)0, L_INCR);
     137:
     138:     /* Read in exec structure. */
     139:     nr = read(rfd, (char *)&ebuf, sizeof(struct exec));
     140:     if (nr != sizeof(struct exec))
     141:         goto bad1;
     142:
     143:     /* Check magic number and symbol count. */
     144:     if (N_BADMAG(ebuf) || ebuf.a_syms == 0)
     145:         goto bad1;
     146:
     147:     /* First four bytes are the table size. */
     148:     sympos = N_STROFF(ebuf) + r_off;
     149:
     150:     /* Seek to symbol table. */
     151:     if (fseek(fp, (off_t)N_SYMOFF(ebuf) + r_off, L_SET) == (off_t)-1)
     152:         goto bad1;
     153:
     154:     /* Save starting point in symbol chain */
     155:     savnext = pnext;
     156:
     157:     /* For each symbol read the nlist entry and save it as necessary. */
     158:     nsyms = ebuf.a_syms / sizeof(struct nlist);
     159:     while (nsyms--) {
     160:         if (!fread((char *)&nl, sizeof(struct nlist), 1, fp)) {
     161:             if (feof(fp))
     162:                 badfmt();
     163:             error(archive);
     164:         }
     165:
     166:         /* Ignore if no name or local. */
     167:         if (!nl.n_un.n_strx || !(nl.n_type & N_EXT))
     168:             continue;
     169:
     170:         /*
     171: 		 * If the symbol is an undefined external and the n_value
     172: 		 * field is non-zero, keep it.
     173: 		 */
     174:         if ((nl.n_type & N_TYPE) == N_UNDF && !nl.n_value)
     175:             continue;
     176:
     177:         rp = (RLIB *)emalloc(sizeof(RLIB));
     178:         rp->pos = sympos + nl.n_un.n_strx;
     179:         rp->next = NULL;
     180:
     181:         /* Build in forward order for "ar -m" command. */
     182:         *pnext = rp;
     183:         pnext = &rp->next;
     184:         ++symcnt;
     185:     }
     186:     for (rp = *savnext; rp; rp = rp->next) {
     187:         fseek(fp, rp->pos, L_SET);
     188:         symlen = sgets(sym, sizeof (sym), fp);
     189:         rp->sym = (char *)emalloc(symlen);
     190:         bcopy(sym, rp->sym, symlen);
     191:         rp->symlen = symlen;
     192:         rp->pos = w_off;
     193:         tsymlen += symlen;
     194:     }
     195: bad1:   (void)lseek(rfd, (off_t)r_off, L_SET);
     196: }
     197:
     198: /*
     199:  * symobj --
     200:  *	Write the symbol table into the archive, computing offsets as
     201:  *	writing.
     202:  */
     203: static void
     204: symobj()
     205: {
     206:     register RLIB *rp, *next;
     207:     struct ranlib rn;
     208:     char hb[sizeof(struct ar_hdr) + 1], pad;
     209:     long ransize, size, stroff;
     210:     gid_t getgid();
     211:     uid_t getuid();
     212:
     213:     /* Rewind the archive, leaving the magic number. */
     214:     if (fseek(fp, (off_t)SARMAG, L_SET) == (off_t)-1)
     215:         error(archive);
     216:
     217:     /* Size of the ranlib archive file, pad if necessary. */
     218:     ransize = sizeof(long) +
     219:         symcnt * sizeof(struct ranlib) + sizeof(long) + tsymlen;
     220:     if (ransize & 01) {
     221:         ++ransize;
     222:         pad = '\n';
     223:     } else
     224:         pad = '\0';
     225:
     226:     /* Put out the ranlib archive file header. */
     227:     (void)sprintf(hb, HDR2, RANLIBMAG, 0L, getuid(), getgid(),
     228:         0666 & ~umask(0), ransize, ARFMAG);
     229:     if (!fwrite(hb, sizeof(struct ar_hdr), 1, fp))
     230:         error(tname);
     231:
     232:     /* First long is the size of the ranlib structure section. */
     233:     size = symcnt * sizeof(struct ranlib);
     234:     if (!fwrite((char *)&size, sizeof(size), 1, fp))
     235:         error(tname);
     236:
     237:     /* Offset of the first archive file. */
     238:     size = SARMAG + sizeof(struct ar_hdr) + ransize;
     239:
     240:     /*
     241: 	 * Write out the ranlib structures.  The offset into the string
     242: 	 * table is cumulative, the offset into the archive is the value
     243: 	 * set in rexec() plus the offset to the first archive file.
     244: 	 */
     245:     for (rp = rhead, stroff = 0; rp; rp = rp->next) {
     246:         rn.ran_un.ran_strx = stroff;
     247:         stroff += rp->symlen;
     248:         rn.ran_off = size + rp->pos;
     249:         if (!fwrite((char *)&rn, sizeof(struct ranlib), 1, fp))
     250:             error(archive);
     251:     }
     252:
     253:     /* Second long is the size of the string table. */
     254:     if (!fwrite((char *)&tsymlen, sizeof(tsymlen), 1, fp))
     255:         error(tname);
     256:
     257:     /* Write out the string table. */
     258:     for (rp = rhead; rp; ) {
     259:         if (!fwrite(rp->sym, rp->symlen, 1, fp))
     260:             error(tname);
     261:         (void)free(rp->sym);
     262:         next = rp->next;
     263:         free(rp);
     264:         rp = next;
     265:     }
     266:
     267:     if (pad && !fwrite(&pad, sizeof(pad), 1, fp))
     268:         error(tname);
     269:
     270:     (void)fflush(fp);
     271: }
     272:
     273: sgets(buf, n, fp)
     274:     char *buf;
     275:     int n;
     276:     register FILE *fp;
     277:     {
     278:     register int i, c;
     279:
     280:     n--;                /* room for null */
     281:     for (i = 0; i < n; i++)
     282:         {
     283:         c = getc(fp);
     284:         if  (c == EOF || c == 0)
     285:             break;
     286:         *buf++ = c;
     287:         }
     288:     *buf = '\0';
     289:     return(i + 1);
     290:     }

#### Defined functions

build defined in line 72; used 1 times

- in /usr/src/usr.bin/ranlib/ranlib.c line 78

rexec defined in line 119; used 2 times

- in line 67, 92

sgets defined in line 273; used 1 times

- in line 188

symobj defined in line 203; used 2 times

- in line 67, 98

#### Defined variables

pnext defined in line 64; used 5 times

- in line 85, 95, 155, 182-183(2)

rhead defined in line 64; used 3 times

- in line 85, 245, 258

sccsid defined in line 38; never used
symcnt defined in line 69; used 4 times

- in line 86, 184, 219, 233

tsymlen defined in line 70; used 5 times

- in line 86, 193, 219, 254(2)

#### Defined struct's

_rlib defined in line 58; used 2 times

- in line 59(2)

#### Defined typedef's

RLIB defined in line 63; used 6 times

- in line 64, 124-125(2), 177(2), 206

Last modified: 1994-01-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1668 |