1/* Clean up working files. */ |
2 |
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 |
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. |
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 |
41mainProg(rcscleanId, "rcsclean", "$Id: rcsclean.c,v 5.9 1995/06/16 06:19:24 eggert Exp $") |
42{ 43 static char const usage[] = |
44 "\nrcsclean: usage: rcsclean -ksubst -{nqru}[rev] -T -Vn -xsuff -zzone file ..."; |
45 46 static struct buf revision; 47 48 char *a, **newargv; 49 char const *rev, *p; |
50 int dounlock, expmode, perform, unlocked, unlockflag, waslocked; 51 int Ttimeflag; |
52 struct hshentries *deltas; 53 struct hshentry *delta; 54 struct stat workstat; 55 56 setrid(); 57 58 expmode = -1; |
59 rev = 0; |
60 suffixes = X_DEFAULT; 61 perform = true; 62 unlockflag = false; |
63 Ttimeflag = false; |
64 65 argc = getRCSINIT(argc, argv, &newargv); 66 argv = newargv; 67 for (;;) { |
68 if (--argc < 1) { |
69# if has_dirent 70 argc = get_directory(".", &newargv); 71 argv = newargv; 72 break; 73# else |
74 faterror("no pathnames specified"); |
75# endif 76 } 77 a = *++argv; |
78 if (!*a || *a++ != '-') |
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 |
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 |
126 default: 127 unknown: |
128 error("unknown option: %s%s", *argv, usage); |
129 } 130 } 131 |
132 dounlock = perform & unlockflag; 133 134 if (nerror) 135 cleanup(); 136 else 137 for (; 0 < argc; cleanup(), ++argv, --argc) { 138 |
139 ffree(); 140 141 if (!( |
142 0 < pairnames( |
143 argc, argv, |
144 dounlock ? rcswriteopen : rcsreadopen, |
145 true, true 146 ) && |
147 (workptr = Iopen(workname, FOPEN_R_WORK, &workstat)) |
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 |
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; |
184 if (unlocked<waslocked && workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH)) 185 continue; 186 |
187 if (unlocked && !checkaccesslist()) |
188 continue; 189 |
190 if (dorewrite(dounlock, unlocked) != 0) 191 continue; 192 |
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 ( |
205 !delta ? workstat.st_size!=0 : |
206 0 < rcsfcmp( |
207 workptr, &workstat, 208 buildrevision(deltas, delta, (FILE*)0, false), 209 delta |
210 ) 211 ) 212 continue; 213 214 if (quietflag < unlocked) |
215 aprintf(stdout, "rcs -u%s %s\n", delta->num, RCSname); |
216 |
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 } |
224 225 if (!quietflag) |
226 aprintf(stdout, "rm -f %s\n", workname); |
227 Izclose(&workptr); |
228 if (perform && un_link(workname) != 0) 229 eerror(workname); |
230 |
231 } |
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); |
246 ORCSclose(); |
247 dirtempunlink(); 248} 249 |
250#if RCS_lint 251# define exiterr rcscleanExit |
252#endif |
253 void |
254exiterr() 255{ |
256 ORCSerror(); |
257 dirtempunlink(); 258 tempunlink(); 259 _exit(EXIT_FAILURE); 260} 261 262 static int 263unlock(delta) 264 struct hshentry *delta; 265{ |
266 register struct rcslock **al, *l; |
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; |
303 if (en[0]=='.' && (!en[1] || (en[1]=='.' && !en[2]))) |
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 } |
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) |
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 |