new error message (if you can't rm 'cause you're not owner)
[unix-history] / usr / src / bin / rm / rm.c
CommitLineData
563bb122 1static char *sccsid = "@(#)rm.c 4.4 (Berkeley) %G%";
ae80f4a2 2int errcode;
563bb122 3short uid, euid;
ae80f4a2
BJ
4
5#include <stdio.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <sys/dir.h>
9
10char *sprintf();
11
12main(argc, argv)
13char *argv[];
14{
15 register char *arg;
16 int fflg, iflg, rflg;
17
18 fflg = 0;
19 if (isatty(0) == 0)
20 fflg++;
21 iflg = 0;
22 rflg = 0;
563bb122
BJ
23 uid = getuid();
24 euid = geteuid();
ae80f4a2
BJ
25 while(argc>1 && argv[1][0]=='-') {
26 arg = *++argv;
27 argc--;
ca02483b
BJ
28
29 /*
30 * all files following a null option are considered file names
31 */
32 if (*(arg+1) == '\0') break;
33
ae80f4a2
BJ
34 while(*++arg != '\0')
35 switch(*arg) {
36 case 'f':
37 fflg++;
38 break;
39 case 'i':
40 iflg++;
41 break;
42 case 'r':
43 rflg++;
44 break;
45 default:
46 printf("rm: unknown option %s\n", *argv);
47 exit(1);
48 }
49 }
50 while(--argc > 0) {
51 if(!strcmp(*++argv, "..")) {
52 fprintf(stderr, "rm: cannot remove `..'\n");
53 continue;
54 }
55 rm(*argv, fflg, rflg, iflg, 0);
56 }
57
58 exit(errcode);
59}
60
61rm(arg, fflg, rflg, iflg, level)
62char arg[];
63{
64 struct stat buf;
65 struct direct direct;
66 char name[100];
67 int d;
68
69 if(stat(arg, &buf)) {
70 if (fflg==0) {
71 printf("rm: %s nonexistent\n", arg);
72 ++errcode;
73 }
74 return;
75 }
76 if ((buf.st_mode&S_IFMT) == S_IFDIR) {
77 if(rflg) {
78 if (access(arg, 02) < 0) {
79 if (fflg==0)
80 printf("%s not changed\n", arg);
81 errcode++;
82 return;
83 }
84 if(iflg && level!=0) {
28c2b1a2 85 printf("remove directory %s? ", arg);
ae80f4a2
BJ
86 if(!yes())
87 return;
88 }
89 if((d=open(arg, 0)) < 0) {
28c2b1a2 90 printf("rm: cannot read %s?\n", arg);
ae80f4a2
BJ
91 exit(1);
92 }
93 while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) {
94 if(direct.d_ino != 0 && !dotname(direct.d_name)) {
95 sprintf(name, "%s/%.14s", arg, direct.d_name);
96 rm(name, fflg, rflg, iflg, level+1);
97 }
98 }
99 close(d);
100 errcode += rmdir(arg, iflg);
101 return;
102 }
103 printf("rm: %s directory\n", arg);
104 ++errcode;
105 return;
106 }
107
108 if(iflg) {
28c2b1a2 109 printf("rm: remove %s? ", arg);
ae80f4a2
BJ
110 if(!yes())
111 return;
112 }
113 else if(!fflg) {
114 if (access(arg, 02)<0) {
563bb122
BJ
115 if (uid == buf.st_uid || euid == buf.st_uid) {
116 printf("rm: override protection %o for %s? ",
117 buf.st_mode&0777, arg);
118 if(!yes())
119 return;
120 } else {
121 printf("rm: %s: not owner.\n", arg);
ae80f4a2 122 return;
563bb122 123 }
ae80f4a2
BJ
124 }
125 }
126 if(unlink(arg) && (fflg==0 || iflg)) {
127 printf("rm: %s not removed\n", arg);
128 ++errcode;
129 }
130}
131
132dotname(s)
133char *s;
134{
135 if(s[0] == '.')
136 if(s[1] == '.')
137 if(s[2] == '\0')
138 return(1);
139 else
140 return(0);
141 else if(s[1] == '\0')
142 return(1);
143 return(0);
144}
145
146rmdir(f, iflg)
147char *f;
148{
149 int status, i;
150
151 if(dotname(f))
152 return(0);
153 if(iflg) {
28c2b1a2 154 printf("rm: remove %s? ", f);
ae80f4a2
BJ
155 if(!yes())
156 return(0);
157 }
158 while((i=fork()) == -1)
159 sleep(3);
160 if(i) {
161 wait(&status);
162 return(status);
163 }
164 execl("/bin/rmdir", "rmdir", f, 0);
165 execl("/usr/bin/rmdir", "rmdir", f, 0);
166 printf("rm: can't find rmdir\n");
167 exit(1);
168}
169
170yes()
171{
172 int i, b;
173
174 i = b = getchar();
175 while(b != '\n' && b != EOF)
176 b = getchar();
177 return(i == 'y');
178}