/* rm - remove files Author: Adri Koppes */ #include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> int errors = 0; int fflag = 0; int iflag = 0; int rflag = 0; int exstatus; main(argc, argv) int argc; char *argv[]; { char *opt; if (argc < 2) usage(); *++argv; --argc; while (**argv == '-') { opt = *argv; while (*++opt != '\0') switch (*opt) { case 'f': fflag++; break; case 'i': iflag++; break; case 'r': rflag++; break; default: std_err("rm: unknown option\n"); usage(); break; } argc--; *++argv; } if (argc < 1) usage(); while (argc--) remove(*argv++); exstatus = (errors == 0 ? 0 : 1); if (fflag) exstatus = 0; exit(exstatus); } usage() { std_err("Usage: rm [-fir] file\n"); exit(1); } remove(name) char *name; { struct stat s; struct direct d; char rname[128], *strcpy(), *strcat(); int fd; if (stat(name, &s)) { if (!fflag) stderr3("rm: ", name, " non-existent\n"); errors++; return; } if (iflag) { stderr3("rm: remove ", name, "? "); if (!confirm()) return; } if ((s.st_mode & S_IFMT) == S_IFDIR) { if (rflag) { if ((fd = open(name, 0)) < 0) { if (!fflag) stderr3("rm: can't open ", name, "\n"); errors++; return; } while (read(fd, (char *) &d, sizeof(struct direct)) > 0) { if (d.d_ino && strcmp("..", d.d_name) && strcmp(".", d.d_name)) { strcpy(rname, name); strcat(rname, "/"); strncat(rname, d.d_name, DIRSIZ); remove(rname); } } close(fd); rem_dir(name); } else { if (!fflag) stderr3("rm: ", name, " is a directory\n"); errors++; return; } } else { if (access(name, 2) && !fflag) { stderr3("rm: remove ", name, " (mode = "); octal(s.st_mode & 0777); std_err(") ? "); if (!confirm()) return; } if (unlink(name)) { if (!fflag) stderr3("rm: ", name, " not removed\n"); errors++; } } } rem_dir(name) char *name; { int status; switch (fork()) { case -1: std_err("rm: can't fork\n"); errors++; return; case 0: execl("/bin/rmdir", "rmdir", name, (char *) 0); execl("/usr/bin/rmdir", "rmdir", name, (char *) 0); std_err("rm: can't exec rmdir\n"); exit(1); default: wait(&status); errors += status; } } confirm() { char c, t; read(0, &c, 1); t = c; do read(0, &t, 1); while (t != '\n' && t != -1); return(c == 'y' || c == 'Y'); } octal(num) unsigned int num; { char a[4]; a[0] = (((num >> 6) & 7) + '0'); a[1] = (((num >> 3) & 7) + '0'); a[2] = ((num & 7) + '0'); a[3] = 0; std_err(a); } stderr3(s1, s2, s3) char *s1, *s2, *s3; { std_err(s1); std_err(s2); std_err(s3); }