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