/* rm - remove files Author: Adri Koppes */ #include "stat.h" struct direct { unsigned short d_ino; char d_name[14]; }; 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, "/"); strcat (rname, d.d_name); 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, " with 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, 0); execl ("/usr/bin/rmdir", "rmdir", name, 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); }