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[] = "@(#)move.c 5.6 (Berkeley) 3/12/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 <stdio.h> 47: #include <ar.h> 48: #include "archive.h" 49: #include "extern.h" 50: #include "pathnames.h" 51: 52: extern CHDR chdr; /* converted header */ 53: extern char *archive; /* archive name */ 54: extern char *tname; /* temporary file "name" */ 55: 56: /* 57: * move -- 58: * Change location of named members in archive - if 'b' or 'i' option 59: * selected then named members are placed before 'posname'. If 'a' 60: * option selected members go after 'posname'. If no options, members 61: * are moved to end of archive. 62: */ 63: move(argv) 64: char **argv; 65: { 66: extern char *posarg, *posname; /* positioning file names */ 67: CF cf; 68: off_t size, tsize; 69: int afd, curfd, mods, tfd1, tfd2, tfd3; 70: char *file; 71: 72: afd = open_archive(O_RDWR); 73: mods = options & (AR_A|AR_B); 74: 75: tfd1 = tmp(); /* Files before key file. */ 76: tfd2 = tmp(); /* Files selected by user. */ 77: tfd3 = tmp(); /* Files after key file. */ 78: 79: /* 80: * Break archive into three parts -- selected entries and entries 81: * before and after the key entry. If positioning before the key, 82: * place the key at the beginning of the after key entries and if 83: * positioning after the key, place the key at the end of the before 84: * key entries. Put it all back together at the end. 85: */ 86: 87: /* Read and write to an archive; pad on both. */ 88: SETCF(afd, archive, 0, tname, RPAD|WPAD); 89: for (curfd = tfd1; get_arobj(afd);) { 90: if (*argv && (file = files(argv))) { 91: if (options & AR_V) 92: (void)printf("m - %s\n", file); 93: cf.wfd = tfd2; 94: put_arobj(&cf, (struct stat *)NULL); 95: continue; 96: } 97: if (mods && compare(posname)) { 98: mods = 0; 99: if (options & AR_B) 100: curfd = tfd3; 101: cf.wfd = curfd; 102: put_arobj(&cf, (struct stat *)NULL); 103: if (options & AR_A) 104: curfd = tfd3; 105: } else { 106: cf.wfd = curfd; 107: put_arobj(&cf, (struct stat *)NULL); 108: } 109: } 110: 111: if (mods) { 112: (void)fprintf(stderr, "ar: %s: archive member not found.\n", 113: posarg); 114: close_archive(afd); 115: return(1); 116: } 117: (void)lseek(afd, (off_t)SARMAG, L_SET); 118: 119: SETCF(tfd1, tname, afd, archive, NOPAD); 120: tsize = size = lseek(tfd1, (off_t)0, L_INCR); 121: (void)lseek(tfd1, (off_t)0, L_SET); 122: copy_ar(&cf, size); 123: 124: tsize += size = lseek(tfd2, (off_t)0, L_INCR); 125: (void)lseek(tfd2, (off_t)0, L_SET); 126: cf.rfd = tfd2; 127: copy_ar(&cf, size); 128: 129: tsize += size = lseek(tfd3, (off_t)0, L_INCR); 130: (void)lseek(tfd3, (off_t)0, L_SET); 131: cf.rfd = tfd3; 132: copy_ar(&cf, size); 133: 134: (void)ftruncate(afd, tsize + SARMAG); 135: close_archive(afd); 136: 137: if (*argv) { 138: orphans(argv); 139: return(1); 140: } 141: return(0); 142: }