uuprog

view rm.c @ 0:4f628556fa3e

uuprog initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 25 Aug 2011 08:53:01 +0300
parents
children
line source
1 /*! cc -o rm rm.c */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <signal.h>
6 #include <stdarg.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <dirent.h>
10 #include <sys/stat.h>
12 int rm(const char *path);
13 int rec_rm(const char *path);
14 char askuser(const char *fmt, ...);
15 void sigfunc(int sig);
17 int ask, stop_proc, force, rec, verbose;
19 int main(int argc, char **argv)
20 {
21 int i;
23 signal(SIGINT, sigfunc);
25 for(i=1; i<argc; i++) {
26 if(!stop_proc && argv[i][0] == '-' && argv[i][2] == 0) {
27 switch(argv[i][1]) {
28 case 'f':
29 force = 1;
30 break;
32 case '-':
33 stop_proc = 1;
34 break;
36 case 'i':
37 ask = 1;
38 break;
40 case 'r':
41 case 'R':
42 rec = 1;
43 break;
45 case 'v':
46 verbose = 1;
47 break;
49 default:
50 fprintf(stderr, "invalid option: %s\n", argv[i]);
51 return 1;
52 }
53 } else {
55 if(rm(argv[i]) == -1) {
56 return 1;
57 }
58 }
59 }
61 return 0;
62 }
64 char askuser(const char *fmt, ...)
65 {
66 int c, resp;
67 va_list ap;
69 va_start(ap, fmt);
70 vprintf(fmt, ap);
71 va_end(ap);
73 resp = getchar();
74 do {
75 c = getchar();
76 } while(c != '\n' && c != -1);
78 return resp;
79 }
81 int rm(const char *path)
82 {
83 if(ask) {
84 char c = askuser("remove file `%s'? ", path);
86 if(c != 'y' && c != 'Y') {
87 return 0;
88 }
89 }
91 if(unlink(path) == -1) {
92 if((errno != EISDIR || rec_rm(path) == -1) && !force) {
93 fprintf(stderr, "cannot remove \"%s\": %s\n", path, strerror(errno));
94 return -1;
95 }
96 } else {
97 if(verbose) {
98 printf("removed `%s'\n", path);
99 }
100 }
101 return 0;
102 }
104 int rec_rm(const char *path)
105 {
106 DIR *dir;
107 struct dirent *dent;
109 if(ask) {
110 char c = askuser("descend into directory `%s'? ", path);
112 if(c != 'y' && c != 'Y') {
113 return 0;
114 }
115 }
117 if(!(dir = opendir(path))) {
118 return force ? 0 : -1;
119 }
121 while((dent = readdir(dir))) {
122 struct stat st;
124 if(stat(dent->d_name, &st) == -1) {
125 if(force) continue;
126 closedir(dir);
127 return -1;
128 }
130 if(S_ISDIR(st.st_mode)) {
131 if(rec_rm(dent->d_name) == -1) {
132 closedir(dir);
133 return -1;
134 }
135 } else {
136 if(rm(dent->d_name) == -1) {
137 closedir(dir);
138 return -1;
139 }
140 }
141 }
143 if(verbose) {
144 printf("removed directory: `%s'\n", path);
145 }
147 closedir(dir);
148 return 0;
149 }
151 void sigfunc(int sig)
152 {
153 exit(1);
154 }