386BSD 0.1 development
[unix-history] / usr / src / usr.bin / ar / move.c
CommitLineData
c2fd5c94
WJ
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#ifndef lint
38static char sccsid[] = "@(#)move.c 5.6 (Berkeley) 3/12/91";
39#endif /* not lint */
40
41#include <sys/param.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <dirent.h>
45#include <unistd.h>
46#include <stdio.h>
47#include <ar.h>
48#include "archive.h"
49#include "extern.h"
50#include "pathnames.h"
51
52extern CHDR chdr; /* converted header */
53extern char *archive; /* archive name */
54extern 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 */
63move(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, SEEK_SET);
118
119 SETCF(tfd1, tname, afd, archive, NOPAD);
120 tsize = size = lseek(tfd1, (off_t)0, SEEK_CUR);
121 (void)lseek(tfd1, (off_t)0, SEEK_SET);
122 copy_ar(&cf, size);
123
124 tsize += size = lseek(tfd2, (off_t)0, SEEK_CUR);
125 (void)lseek(tfd2, (off_t)0, SEEK_SET);
126 cf.rfd = tfd2;
127 copy_ar(&cf, size);
128
129 tsize += size = lseek(tfd3, (off_t)0, SEEK_CUR);
130 (void)lseek(tfd3, (off_t)0, SEEK_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}