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

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