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
rexec defined in line 119; used 2 times
sgets defined in line 273; used 1 times
symobj defined in line 203; used 2 times

Defined variables

pnext defined in line 64; used 5 times
rhead defined in line 64; used 3 times
sccsid defined in line 38; never used
symcnt defined in line 69; used 4 times
tsymlen defined in line 70; used 5 times

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
Last modified: 1994-01-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3883
Valid CSS Valid XHTML 1.0 Strict