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 }