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(DOSCCS) && !defined(lint)
  38: static char sccsid[] = "@(#)replace.c	5.8 (Berkeley) 3/15/91";
  39: #endif
  40: 
  41: #include <sys/param.h>
  42: #include <sys/stat.h>
  43: #include <fcntl.h>
  44: #include <sys/dir.h>
  45: #include <sys/file.h>
  46: #include <errno.h>
  47: #include <ar.h>
  48: #include <stdio.h>
  49: #include <string.h>
  50: #include "archive.h"
  51: #include "extern.h"
  52: 
  53: extern int errno;
  54: extern CHDR chdr;           /* converted header */
  55: extern char *archive;           /* archive name */
  56: extern char *tname;                     /* temporary file "name" */
  57: 
  58: /*
  59:  * replace --
  60:  *	Replace or add named members to archive.  Entries already in the
  61:  *	archive are swapped in place.  Others are added before or after
  62:  *	the key entry, based on the a, b and i options.  If the u option
  63:  *	is specified, modification dates select for replacement.
  64:  */
  65: replace(argv)
  66:     char **argv;
  67: {
  68:     extern char *posarg, *posname;  /* positioning file name */
  69:     register char *file;
  70:     register int afd, curfd, mods, sfd;
  71:     struct stat sb;
  72:     CF cf;
  73:     off_t size, tsize;
  74:     int err, exists, tfd1, tfd2;
  75:     char *rname();
  76: 
  77:     err = 0;
  78:     /*
  79: 	 * If doesn't exist, simply append to the archive.  There's
  80: 	 * a race here, but it's pretty short, and not worth fixing.
  81: 	 */
  82:     exists = !stat(archive, &sb);
  83:     afd = open_archive(O_CREAT|O_RDWR);
  84: 
  85:     if (!exists) {
  86:         tfd1 = -1;
  87:         tfd2 = tmp();
  88:         goto append;
  89:     }
  90: 
  91:     tfd1 = tmp();           /* Files before key file. */
  92:     tfd2 = tmp();           /* Files after key file. */
  93: 
  94:     /*
  95: 	 * Break archive into two parts -- entries before and after the key
  96: 	 * entry.  If positioning before the key, place the key at the
  97: 	 * beginning of the after key entries and if positioning after the
  98: 	 * key, place the key at the end of the before key entries.  Put it
  99: 	 * all back together at the end.
 100: 	 */
 101:     mods = (options & (AR_A|AR_B));
 102:     for (curfd = tfd1; get_arobj(afd);) {
 103:         if (*argv && (file = files(argv))) {
 104:             if ((sfd = open(file, O_RDONLY)) < 0) {
 105:                 err = 1;
 106:                 (void)fprintf(stderr, "ar: %s: %s.\n",
 107:                     file, strerror(errno));
 108:                 goto useold;
 109:             }
 110:             (void)fstat(sfd, &sb);
 111:             if (options & AR_U && sb.st_mtime <= chdr.date) {
 112:                 (void)close(sfd);
 113:                 goto useold;
 114:             }
 115: 
 116:             if (options & AR_V)
 117:                  (void)printf("r - %s\n", file);
 118: 
 119:             /* Read from disk, write to an archive; pad on write */
 120:             SETCF(sfd, file, curfd, tname, WPAD);
 121:             put_arobj(&cf, &sb);
 122:             (void)close(sfd);
 123:             skip_arobj(afd);
 124:             continue;
 125:         }
 126: 
 127:         if (mods && compare(posname)) {
 128:             mods = 0;
 129:             if (options & AR_B)
 130:                 curfd = tfd2;
 131:             /* Read and write to an archive; pad on both. */
 132:             SETCF(afd, archive, curfd, tname, RPAD|WPAD);
 133:             put_arobj(&cf, (struct stat *)NULL);
 134:             if (options & AR_A)
 135:                 curfd = tfd2;
 136:         } else {
 137:             /* Read and write to an archive; pad on both. */
 138: useold:         SETCF(afd, archive, curfd, tname, RPAD|WPAD);
 139:             put_arobj(&cf, (struct stat *)NULL);
 140:         }
 141:     }
 142: 
 143:     if (mods) {
 144:         (void)fprintf(stderr, "ar: %s: archive member not found.\n",
 145:             posarg);
 146:                 close_archive(afd);
 147:                 return(1);
 148:         }
 149: 
 150:     /* Append any left-over arguments to the end of the after file. */
 151: append: while (file = *argv++) {
 152:         if (options & AR_V)
 153:             (void)printf("a - %s\n", file);
 154:         if ((sfd = open(file, O_RDONLY)) < 0) {
 155:             err = 1;
 156:             (void)fprintf(stderr, "ar: %s: %s.\n",
 157:                 file, strerror(errno));
 158:             continue;
 159:         }
 160:         (void)fstat(sfd, &sb);
 161:         /* Read from disk, write to an archive; pad on write. */
 162:         SETCF(sfd, file,
 163:             options & (AR_A|AR_B) ? tfd1 : tfd2, tname, WPAD);
 164:         put_arobj(&cf, &sb);
 165:         (void)close(sfd);
 166:     }
 167: 
 168:     (void)lseek(afd, (off_t)SARMAG, L_SET);
 169: 
 170:     SETCF(tfd1, tname, afd, archive, NOPAD);
 171:     if (tfd1 != -1) {
 172:         tsize = size = lseek(tfd1, (off_t)0, L_INCR);
 173:         (void)lseek(tfd1, (off_t)0, L_SET);
 174:         copy_ar(&cf, size);
 175:     } else
 176:         tsize = 0;
 177: 
 178:     tsize += size = lseek(tfd2, (off_t)0, L_INCR);
 179:     (void)lseek(tfd2, (off_t)0, L_SET);
 180:     cf.rfd = tfd2;
 181:     copy_ar(&cf, size);
 182: 
 183:     (void)ftruncate(afd, tsize + SARMAG);
 184:     close_archive(afd);
 185:     return(err);
 186: }

Defined functions

replace defined in line 65; used 2 times

Defined variables

sccsid defined in line 38; never used
Last modified: 1993-09-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3528
Valid CSS Valid XHTML 1.0 Strict