Deleted Added
full compact
rcsclean.c (9) rcsclean.c (11891)
1/* rcsclean - clean up working files */
1/* Clean up working files. */
2
2
3/* Copyright 1991 by Paul Eggert
3/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
4 Distributed under license by the Free Software Foundation, Inc.
5
6This file is part of RCS.
7
8RCS is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13RCS is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
4 Distributed under license by the Free Software Foundation, Inc.
5
6This file is part of RCS.
7
8RCS is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13RCS is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with RCS; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19along with RCS; see the file COPYING.
20If not, write to the Free Software Foundation,
2159 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Report problems and direct all questions to:
23
24 rcs-bugs@cs.purdue.edu
25
26*/
27
28#include "rcsbase.h"
29
30#if has_dirent
31 static int get_directory P((char const*,char***));
32#endif
33
34static int unlock P((struct hshentry *));
35static void cleanup P((void));
36
37static RILE *workptr;
38static int exitstatus;
39
22
23Report problems and direct all questions to:
24
25 rcs-bugs@cs.purdue.edu
26
27*/
28
29#include "rcsbase.h"
30
31#if has_dirent
32 static int get_directory P((char const*,char***));
33#endif
34
35static int unlock P((struct hshentry *));
36static void cleanup P((void));
37
38static RILE *workptr;
39static int exitstatus;
40
40mainProg(rcscleanId, "rcsclean", "$Id: rcsclean.c,v 5.1 1991/11/03 01:11:44 eggert Exp $")
41mainProg(rcscleanId, "rcsclean", "$Id: rcsclean.c,v 5.9 1995/06/16 06:19:24 eggert Exp $")
41{
42 static char const usage[] =
42{
43 static char const usage[] =
43 "\nrcsclean: usage: rcsclean [-ksubst] [-{nqru}[rev]] [-Vn] [-xsuffixes] [file ...]";
44 "\nrcsclean: usage: rcsclean -ksubst -{nqru}[rev] -T -Vn -xsuff -zzone file ...";
44
45 static struct buf revision;
46
47 char *a, **newargv;
48 char const *rev, *p;
45
46 static struct buf revision;
47
48 char *a, **newargv;
49 char const *rev, *p;
49 int changelock, expmode, perform, unlocked, unlockflag, waslocked;
50 int dounlock, expmode, perform, unlocked, unlockflag, waslocked;
51 int Ttimeflag;
50 struct hshentries *deltas;
51 struct hshentry *delta;
52 struct stat workstat;
53
54 setrid();
55
56 expmode = -1;
52 struct hshentries *deltas;
53 struct hshentry *delta;
54 struct stat workstat;
55
56 setrid();
57
58 expmode = -1;
57 rev = nil;
59 rev = 0;
58 suffixes = X_DEFAULT;
59 perform = true;
60 unlockflag = false;
60 suffixes = X_DEFAULT;
61 perform = true;
62 unlockflag = false;
63 Ttimeflag = false;
61
62 argc = getRCSINIT(argc, argv, &newargv);
63 argv = newargv;
64 for (;;) {
64
65 argc = getRCSINIT(argc, argv, &newargv);
66 argv = newargv;
67 for (;;) {
65 if (--argc <= 0) {
68 if (--argc < 1) {
66# if has_dirent
67 argc = get_directory(".", &newargv);
68 argv = newargv;
69 break;
70# else
69# if has_dirent
70 argc = get_directory(".", &newargv);
71 argv = newargv;
72 break;
73# else
71 faterror("no file names specified");
74 faterror("no pathnames specified");
72# endif
73 }
74 a = *++argv;
75# endif
76 }
77 a = *++argv;
75 if (*a++ != '-')
78 if (!*a || *a++ != '-')
76 break;
77 switch (*a++) {
78 case 'k':
79 if (0 <= expmode)
80 redefined('k');
81 if ((expmode = str2expmode(a)) < 0)
82 goto unknown;
83 break;

--- 9 unchanged lines hidden (view full) ---

93 handle_revision:
94 if (*a) {
95 if (rev)
96 warn("redefinition of revision number");
97 rev = a;
98 }
99 break;
100
79 break;
80 switch (*a++) {
81 case 'k':
82 if (0 <= expmode)
83 redefined('k');
84 if ((expmode = str2expmode(a)) < 0)
85 goto unknown;
86 break;

--- 9 unchanged lines hidden (view full) ---

96 handle_revision:
97 if (*a) {
98 if (rev)
99 warn("redefinition of revision number");
100 rev = a;
101 }
102 break;
103
104 case 'T':
105 if (*a)
106 goto unknown;
107 Ttimeflag = true;
108 break;
109
101 case 'u':
102 unlockflag = true;
103 goto handle_revision;
104
105 case 'V':
106 setRCSversion(*argv);
107 break;
108
109 case 'x':
110 suffixes = a;
111 break;
112
110 case 'u':
111 unlockflag = true;
112 goto handle_revision;
113
114 case 'V':
115 setRCSversion(*argv);
116 break;
117
118 case 'x':
119 suffixes = a;
120 break;
121
122 case 'z':
123 zone_set(a);
124 break;
125
113 default:
114 unknown:
126 default:
127 unknown:
115 faterror("unknown option: %s%s", *argv, usage);
128 error("unknown option: %s%s", *argv, usage);
116 }
117 }
118
129 }
130 }
131
119 do {
132 dounlock = perform & unlockflag;
133
134 if (nerror)
135 cleanup();
136 else
137 for (; 0 < argc; cleanup(), ++argv, --argc) {
138
120 ffree();
121
122 if (!(
139 ffree();
140
141 if (!(
123 0 < pairfilenames(
142 0 < pairnames(
124 argc, argv,
143 argc, argv,
125 unlockflag&perform ? rcswriteopen : rcsreadopen,
144 dounlock ? rcswriteopen : rcsreadopen,
126 true, true
127 ) &&
145 true, true
146 ) &&
128 (workptr = Iopen(workfilename,FOPEN_R_WORK,&workstat))
147 (workptr = Iopen(workname, FOPEN_R_WORK, &workstat))
129 ))
130 continue;
131
148 ))
149 continue;
150
151 if (same_file(RCSstat, workstat, 0)) {
152 rcserror("RCS file is the same as working file %s.",
153 workname
154 );
155 continue;
156 }
157
132 gettree();
133
134 p = 0;
135 if (rev) {
136 if (!fexpandsym(rev, &revision, workptr))
137 continue;
138 p = revision.string;
139 } else if (Head)

--- 10 unchanged lines hidden (view full) ---

150 delta = 0;
151 deltas = 0; /* Keep lint happy. */
152 if (p && !(delta = genrevs(p,(char*)0,(char*)0,(char*)0,&deltas)))
153 continue;
154
155 waslocked = delta && delta->lockedby;
156 locker_expansion = unlock(delta);
157 unlocked = locker_expansion & unlockflag;
158 gettree();
159
160 p = 0;
161 if (rev) {
162 if (!fexpandsym(rev, &revision, workptr))
163 continue;
164 p = revision.string;
165 } else if (Head)

--- 10 unchanged lines hidden (view full) ---

176 delta = 0;
177 deltas = 0; /* Keep lint happy. */
178 if (p && !(delta = genrevs(p,(char*)0,(char*)0,(char*)0,&deltas)))
179 continue;
180
181 waslocked = delta && delta->lockedby;
182 locker_expansion = unlock(delta);
183 unlocked = locker_expansion & unlockflag;
158 changelock = unlocked & perform;
159 if (unlocked<waslocked && workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH))
160 continue;
161
184 if (unlocked<waslocked && workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH))
185 continue;
186
162 if (!dorewrite(unlockflag, changelock))
187 if (unlocked && !checkaccesslist())
163 continue;
164
188 continue;
189
190 if (dorewrite(dounlock, unlocked) != 0)
191 continue;
192
165 if (0 <= expmode)
166 Expand = expmode;
167 else if (
168 waslocked &&
169 Expand == KEYVAL_EXPAND &&
170 WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
171 )
172 Expand = KEYVALLOCK_EXPAND;
173
174 getdesc(false);
175
176 if (
193 if (0 <= expmode)
194 Expand = expmode;
195 else if (
196 waslocked &&
197 Expand == KEYVAL_EXPAND &&
198 WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
199 )
200 Expand = KEYVALLOCK_EXPAND;
201
202 getdesc(false);
203
204 if (
177 !delta ? workstat.st_size!=0 :
205 !delta ? workstat.st_size!=0 :
178 0 < rcsfcmp(
206 0 < rcsfcmp(
179 workptr, &workstat,
180 buildrevision(deltas, delta, (FILE*)0, false),
181 delta
207 workptr, &workstat,
208 buildrevision(deltas, delta, (FILE*)0, false),
209 delta
182 )
183 )
184 continue;
185
186 if (quietflag < unlocked)
210 )
211 )
212 continue;
213
214 if (quietflag < unlocked)
187 aprintf(stdout, "rcs -u%s %s\n", delta->num, RCSfilename);
215 aprintf(stdout, "rcs -u%s %s\n", delta->num, RCSname);
188
216
189 if_advise_access(changelock && deltas->first != delta,
190 finptr, MADV_SEQUENTIAL
191 );
192 if (!donerewrite(changelock))
193 continue;
217 if (perform & unlocked) {
218 if_advise_access(deltas->first != delta, finptr, MADV_SEQUENTIAL);
219 if (donerewrite(true,
220 Ttimeflag ? RCSstat.st_mtime : (time_t)-1
221 ) != 0)
222 continue;
223 }
194
195 if (!quietflag)
224
225 if (!quietflag)
196 aprintf(stdout, "rm -f %s\n", workfilename);
226 aprintf(stdout, "rm -f %s\n", workname);
197 Izclose(&workptr);
227 Izclose(&workptr);
198 if (perform && un_link(workfilename) != 0)
199 eerror(workfilename);
228 if (perform && un_link(workname) != 0)
229 eerror(workname);
200
230
201 } while (cleanup(), ++argv, 0 < --argc);
231 }
202
203 tempunlink();
204 if (!quietflag)
205 Ofclose(stdout);
206 exitmain(exitstatus);
207}
208
209 static void
210cleanup()
211{
212 if (nerror) exitstatus = EXIT_FAILURE;
213 Izclose(&finptr);
214 Izclose(&workptr);
215 Ozclose(&fcopy);
232
233 tempunlink();
234 if (!quietflag)
235 Ofclose(stdout);
236 exitmain(exitstatus);
237}
238
239 static void
240cleanup()
241{
242 if (nerror) exitstatus = EXIT_FAILURE;
243 Izclose(&finptr);
244 Izclose(&workptr);
245 Ozclose(&fcopy);
216 Ozclose(&frewrite);
246 ORCSclose();
217 dirtempunlink();
218}
219
247 dirtempunlink();
248}
249
220#if lint
221# define exiterr rcscleanExit
250#if RCS_lint
251# define exiterr rcscleanExit
222#endif
252#endif
223 exiting void
253 void
224exiterr()
225{
254exiterr()
255{
256 ORCSerror();
226 dirtempunlink();
227 tempunlink();
228 _exit(EXIT_FAILURE);
229}
230
231 static int
232unlock(delta)
233 struct hshentry *delta;
234{
257 dirtempunlink();
258 tempunlink();
259 _exit(EXIT_FAILURE);
260}
261
262 static int
263unlock(delta)
264 struct hshentry *delta;
265{
235 register struct lock **al, *l;
266 register struct rcslock **al, *l;
236
237 if (delta && delta->lockedby && strcmp(getcaller(),delta->lockedby)==0)
238 for (al = &Locks; (l = *al); al = &l->nextlock)
239 if (l->delta == delta) {
240 *al = l->nextlock;
241 delta->lockedby = 0;
242 return true;
243 }

--- 20 unchanged lines hidden (view full) ---

264 DIR *d;
265 struct dirent *e;
266
267 if (!(d = opendir(dirname)))
268 efaterror(dirname);
269 while ((errno = 0, e = readdir(d))) {
270 char const *en = e->d_name;
271 size_t s = strlen(en) + 1;
267
268 if (delta && delta->lockedby && strcmp(getcaller(),delta->lockedby)==0)
269 for (al = &Locks; (l = *al); al = &l->nextlock)
270 if (l->delta == delta) {
271 *al = l->nextlock;
272 delta->lockedby = 0;
273 return true;
274 }

--- 20 unchanged lines hidden (view full) ---

295 DIR *d;
296 struct dirent *e;
297
298 if (!(d = opendir(dirname)))
299 efaterror(dirname);
300 while ((errno = 0, e = readdir(d))) {
301 char const *en = e->d_name;
302 size_t s = strlen(en) + 1;
272 if (en[0]=='.' && (!en[1] || en[1]=='.' && !en[2]))
303 if (en[0]=='.' && (!en[1] || (en[1]=='.' && !en[2])))
273 continue;
274 if (rcssuffix(en))
275 continue;
276 while (chars_max < s + chars)
277 a = trealloc(char, a, chars_max<<=1);
278 if (entries == entries_max)
279 offset = trealloc(size_t, offset, entries_max<<=1);
280 offset[entries++] = chars;
281 VOID strcpy(a+chars, en);
282 chars += s;
283 }
304 continue;
305 if (rcssuffix(en))
306 continue;
307 while (chars_max < s + chars)
308 a = trealloc(char, a, chars_max<<=1);
309 if (entries == entries_max)
310 offset = trealloc(size_t, offset, entries_max<<=1);
311 offset[entries++] = chars;
312 VOID strcpy(a+chars, en);
313 chars += s;
314 }
284 if (errno || closedir(d) != 0)
315# if void_closedir
316# define close_directory(d) (closedir(d), 0)
317# else
318# define close_directory(d) closedir(d)
319# endif
320 if (errno || close_directory(d) != 0)
285 efaterror(dirname);
286 if (chars)
287 a = trealloc(char, a, chars);
288 else
289 tfree(a);
290 *aargv = p = tnalloc(char*, entries+1);
291 for (i=0; i<entries; i++)
292 *p++ = a + offset[i];
293 *p = 0;
294 tfree(offset);
295 return entries;
296}
297#endif
321 efaterror(dirname);
322 if (chars)
323 a = trealloc(char, a, chars);
324 else
325 tfree(a);
326 *aargv = p = tnalloc(char*, entries+1);
327 for (i=0; i<entries; i++)
328 *p++ = a + offset[i];
329 *p = 0;
330 tfree(offset);
331 return entries;
332}
333#endif