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

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