source: trunk/athena/bin/delete/util.c @ 18055

Revision 18055, 7.6 KB checked in by zacheiss, 22 years ago (diff)
Only remove one instance of .# at a time, rather than doing it in a while loop. Fixes lsdel output and undelete when handling files that have been multiply deleted.
Line 
1/*
2 * $Id: util.c,v 1.33 2002-11-20 19:09:24 zacheiss Exp $
3 *
4 * This program is a replacement for rm.  Instead of actually deleting
5 * files, it marks them for deletion by prefixing them with a ".#"
6 * prefix.
7 *
8 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file "mit-copying.h."
10 */
11
12#if (!defined(lint) && !defined(SABER))
13     static char rcsid_util_c[] = "$Id: util.c,v 1.33 2002-11-20 19:09:24 zacheiss Exp $";
14#endif
15
16#include <stdio.h>
17#include <sys/param.h>
18#include <sys/types.h>
19#include <dirent.h>
20#include <string.h>
21#include <pwd.h>
22#include <errno.h>
23#ifdef HAVE_AFS
24#include <sys/ioctl.h>
25#include <rx/rx.h>
26#include <afs/param.h>
27#include <afs/vice.h>
28#include <netinet/in.h>
29#include <afs/venus.h>
30#endif
31#include "delete_errs.h"
32#include "util.h"
33#include "directories.h"
34#include "mit-copying.h"
35#include "errors.h"
36
37char *convert_to_user_name(real_name, user_name)
38char real_name[];
39char user_name[];  /* RETURN */
40{
41     char *ptr, *q;
42     
43     (void) strcpy(user_name, real_name);
44     ptr = strrindex(user_name, ".#");
45     for (q = ptr; *(q + 2); q++)
46       *q = *(q + 2);
47     *q = '\0';
48     return (user_name);
49}
50
51     
52
53
54
55char *strindex(str, sub_str)
56char *str, *sub_str;
57{
58     char *ptr = str;
59     while (ptr = strchr(ptr, *sub_str)) {
60          if (! strncmp(ptr, sub_str, strlen(sub_str)))
61               return(ptr);
62          ptr++;
63     }
64     return ((char *) NULL);
65}
66
67
68
69char *strrindex(str, sub_str)
70char *str, *sub_str;
71{
72     char *ptr;
73
74     if (strlen(str))
75          ptr = &str[strlen(str) - 1];
76     else
77          return((char *) NULL);
78     while ((*ptr != *sub_str) && (ptr != str)) ptr--;
79     while (ptr != str) {
80          if (! strncmp(ptr, sub_str, strlen(sub_str)))
81               return(ptr);
82          ptr--;
83          while ((*ptr != *sub_str) && (ptr != str)) ptr--;
84     }
85     if (! strncmp(ptr, sub_str, strlen(sub_str)))
86          return(str);
87     else
88          return ((char *) NULL);
89}
90     
91     
92/*
93 * NOTE: Append uses a static array, so its return value must be
94 * copied immediately.
95 */
96char *append(filepath, filename)
97char *filepath, *filename;
98{
99     static char buf[MAXPATHLEN];
100
101     (void) strcpy(buf, filepath);
102     if ((! *filename) || (! *filepath)) {
103          (void) strcpy(buf, filename);
104          return(buf);
105     }
106     if (buf[strlen(buf) - 1] == '/')
107          buf[strlen(buf) - 1] = '\0';
108     if (strlen(buf) + strlen(filename) + 2 > MAXPATHLEN) {
109          set_error(ENAMETOOLONG);
110          strncat(buf, "/", MAXPATHLEN - strlen(buf) - 1);
111          strncat(buf, filename, MAXPATHLEN - strlen(buf) - 1);
112          error(buf);
113          *buf = '\0';
114          return buf;
115     }
116     (void) strcat(buf, "/");
117     (void) strcat(buf, filename);
118     return buf;
119}
120
121
122
123
124yes() {
125     char buf[BUFSIZ];
126     char *val;
127     
128     val = fgets(buf, BUFSIZ, stdin);
129     if (! val) {
130          printf("\n");
131          exit(1);
132     }
133     if (! strchr(buf, '\n')) do
134          (void) fgets(buf + 1, BUFSIZ - 1, stdin);
135     while (! strchr(buf + 1, '\n'));
136     return(*buf == 'y');
137}
138
139
140
141
142char *lastpart(filename)
143char *filename;
144{
145     char *part;
146
147     part = strrchr(filename, '/');
148
149     if (! part)
150          part = filename;
151     else if (part == filename)
152          part++;
153     else if (part - filename + 1 == strlen(filename)) {
154          part = strrchr(--part, '/');
155          if (! part)
156               part = filename;
157          else
158               part++;
159     }
160     else
161          part++;
162
163     return(part);
164}
165
166
167
168
169char *firstpart(filename, rest)
170char *filename;
171char *rest; /* RETURN */
172{
173     char *part;
174     static char buf[MAXPATHLEN];
175
176     (void) strcpy(buf, filename);
177     part = strchr(buf, '/');
178     if (! part) {
179          *rest = '\0';
180          return(buf);
181     }
182     (void) strcpy(rest, part + 1);
183     *part = '\0';
184     return(buf);
185}
186
187
188
189
190
191get_home(buf)
192char *buf;
193{
194     char *user;
195     struct passwd *psw;
196     
197     (void) strcpy(buf, getenv("HOME"));
198     
199     if (*buf)
200          return(0);
201
202     user = getenv("USER");
203     psw = getpwnam(user);
204
205     if (psw) {
206          (void) strcpy(buf, psw->pw_dir);
207          return(0);
208     }
209     
210     psw = getpwuid((int) getuid());
211
212     if (psw) {
213          (void) strcpy(buf, psw->pw_dir);
214          return(0);
215     }
216
217     set_error(NO_HOME_DIR);
218     error("get_home");
219     return error_code;
220}
221
222
223
224
225timed_out(file_ent, current_time, min_days)
226filerec *file_ent;
227time_t current_time, min_days;
228{
229     if ((current_time - file_ent->specs.st_chtime) / 86400 >= min_days)
230          return(1);
231     else
232          return(0);
233}
234
235
236
237int directory_exists(dirname)
238char *dirname;
239{
240     struct stat stat_buf;
241
242     if (stat(dirname, &stat_buf))
243          return(0);
244     else if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
245          return(1);
246     else
247          return(0);
248}
249
250
251
252is_link(name, oldbuf)
253char *name;
254struct stat *oldbuf;
255{
256#ifdef S_IFLNK
257     struct stat statbuf;
258
259     if (oldbuf)
260          statbuf = *oldbuf;
261     else if (lstat(name, &statbuf) < 0) {
262          set_error(errno);
263          error("is_link");
264          return(0);
265     }
266
267     if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
268          return 1;
269     else
270#endif
271          return 0;
272}
273
274
275
276/*
277 * This is one of the few procedures that is allowed to break the
278 * rule of always returning an error value if an error occurs.  That's
279 * because it's stupid to expect a boolean function to do that, and
280 * because defaulting to not being a mountpoint if there is an error
281 * is a reasonable thing to do.
282 */
283/*
284 * The second parameter is optional -- if it is non-NULL, it is
285 * presumed to be a stat structure for the file being passed in.
286 */
287int is_mountpoint(name, oldbuf)
288char *name;
289struct stat *oldbuf;
290{
291     struct stat statbuf;
292     dev_t device;
293     char buf[MAXPATHLEN];
294#ifdef HAVE_AFS
295     struct ViceIoctl blob;
296     char retbuf[MAXPATHLEN];
297     int retval;
298     char *shortname;
299#endif
300
301     /* First way to check for a mount point -- if the device number */
302     /* of name is different from the device number of name/..       */
303     if (oldbuf)
304          statbuf = *oldbuf;
305     else if (lstat(name, &statbuf) < 0) {
306          set_error(errno);
307          error(name);
308          return 0;
309     }
310
311     device = statbuf.st_dev;
312
313     if (strlen(name) + 4 /* length of "/.." + a NULL */ > MAXPATHLEN) {
314          set_error(ENAMETOOLONG);
315          error(name);
316          return 0;
317     }
318
319     strcpy(buf, name);
320     strcat(buf, "/..");
321     if (lstat(buf, &statbuf) < 0) {
322          set_error(errno);
323          error(name);
324          return 0;
325     }
326
327     if (statbuf.st_dev != device)
328          return 1;
329
330#ifdef HAVE_AFS
331     /* Check for AFS mountpoint using the AFS pioctl call. */
332     if ((shortname = lastpart(name)) == name) {
333          strcpy(buf, ".");
334          blob.in = name;
335          blob.in_size = strlen(name) + 1;
336          blob.out = retbuf;
337          blob.out_size = MAXPATHLEN;
338          memset(retbuf, 0, MAXPATHLEN);
339     }
340     else {
341          strncpy(buf, name, shortname - name - 1);
342          buf[shortname - name - 1] = '\0';
343          if (*buf == '\0')
344               strcpy(buf, "/");
345          blob.in = shortname;
346          blob.in_size = strlen(shortname) + 1;
347          blob.out = retbuf;
348          blob.out_size = MAXPATHLEN;
349          memset(retbuf, 0, MAXPATHLEN);
350     }
351
352     retval = pioctl(buf, VIOC_AFS_STAT_MT_PT, &blob, 0);
353
354     if (retval == 0) {
355#ifdef DEBUG
356          printf("%s is an AFS mountpoint, is_mountpoint returning true.\n",
357                 name);
358#endif
359          return 1;
360     }
361     else {
362          if (errno != EINVAL) {
363               set_error(errno);
364               error(name);
365          }
366     }
367#endif /* HAVE_AFS */
368
369     return 0;
370}
371
372#ifdef MALLOC_DEBUG
373char *Malloc(size)
374unsigned size;
375{
376     extern char *malloc();
377
378     static int count = 0;
379     char buf[10];
380     
381     count++;
382
383     fprintf(stderr, "This is call number %d to Malloc, for %u bytes.\n",
384             count, size);
385     fprintf(stdout, "Shall I return NULL for this malloc? ");
386     fgets(buf, 10, stdin);
387     if ((*buf == 'y') || (*buf == 'Y')) {
388          errno = ENOMEM;
389          return ((char *) NULL);
390     }
391     else
392          return (malloc(size));
393}
394#endif
395
396         
Note: See TracBrowser for help on using the repository browser.