# 2.11BSD#431 - /usr/src/bin/rm.c

##### Functions

    append            X
    dotname           X
    main              X
    rm                X
    yes               X

##### Variables

    errcode           X
    fflg              X
    iflg              X
    path              X
    pathp             X
    pathsz            X
    rflg              X

       1: static char *sccsid = "@(#)rm.c	4.18 (Berkeley) 1/6/86";
       2:
       3: /*
       4:  * rm - for ReMoving files, directories & trees.
       5:  */
       6:
       7: #include <stdio.h>
       8: #include <sys/param.h>
       9: #include <sys/stat.h>
      10: #include <sys/dir.h>
      11: #include <sys/file.h>
      12:
      13: int fflg;       /* -f force - supress error messages */
      14: int iflg;       /* -i interrogate user on each file */
      15: int rflg;       /* -r recurse */
      16:
      17: int errcode;    /* true if errors occured */
      18:
      19: char    *strcpy(), *malloc(), *realloc();
      20:
      21: main(argc, argv)
      22:     char *argv[];
      23: {
      24:     register char *arg;
      25:
      26:     fflg = !isatty(0);
      27:     iflg = 0;
      28:     rflg = 0;
      29:     while (argc > 1 && argv[1][0] == '-') {
      30:         arg = *++argv;
      31:         argc--;
      32:
      33:         /*
      34: 		 *  all files following a null option are considered file names
      35: 		 */
      36:         if (arg[1] == '\0')
      37:             break;
      38:
      39:         while (*++arg != '\0')
      40:             switch(*arg) {
      41:             case 'f':
      42:                 fflg++;
      43:                 break;
      44:
      45:             case 'i':
      46:                 iflg++;
      47:                 break;
      48:
      49:             case 'R':
      50:             case 'r':
      51:                 rflg++;
      52:                 break;
      53:
      54:             default:
      55:                 fprintf(stderr, "usage: rm [-rif] file ...\n");
      56:                 exit(1);
      57:             }
      58:     }
      59:
      60:     if (argc < 2 && !fflg) {
      61:         fprintf(stderr, "usage: rm [-rif] file ...\n");
      62:         exit(1);
      63:     }
      64:
      65:     while (--argc > 0)
      66:         (void) rm(*++argv, 0);
      67:
      68:     exit(errcode != 0);
      69: }
      70:
      71: char    *path;      /* pointer to malloc'ed buffer for path */
      72: char    *pathp;     /* current pointer to end of path */
      73: int pathsz;     /* size of path */
      74:
      75: /*
      76:  * Return TRUE if sucessful. Recursive with -r (rflg)
      77:  */
      78: rm(arg, level)
      79:     char arg[];
      80: {
      81:     int ok;             /* true if recursive rm succeeded */
      82:     struct stat buf;        /* for finding out what a file is */
      83:     struct direct *dp;      /* for reading a directory */
      84:     DIR *dirp;          /* for reading a directory */
      85:     char prevname[MAXNAMLEN + 1];   /* previous name for -r */
      86:     char *cp;
      87:
      88:     if (dotname(arg)) {
      89:         fprintf(stderr, "rm: cannot remove `.' or `..'\n");
      90:         return (0);
      91:     }
      92:     if (lstat(arg, &buf)) {
      93:         if (!fflg) {
      94:             fprintf(stderr, "rm: %s nonexistent\n", arg);
      95:             errcode++;
      96:         }
      97:         return (0);     /* error */
      98:     }
      99:     if ((buf.st_mode&S_IFMT) == S_IFDIR) {
     100:         if (!rflg) {
     101:             if (!fflg) {
     102:                 fprintf(stderr, "rm: %s directory\n", arg);
     103:                 errcode++;
     104:             }
     105:             return (0);
     106:         }
     107:         if (iflg && level != 0) {
     108:             printf("rm: remove directory %s? ", arg);
     109:             if (!yes())
     110:                 return (0); /* didn't remove everything */
     111:         }
     112:         if (access(arg, R_OK|W_OK|X_OK) != 0) {
     113:             if (rmdir(arg) == 0)
     114:                 return (1); /* salvaged: removed empty dir */
     115:             if (!fflg) {
     116:                 fprintf(stderr, "rm: %s not changed\n", arg);
     117:                 errcode++;
     118:             }
     119:             return (0);     /* error */
     120:         }
     121:         if ((dirp = opendir(arg)) == NULL) {
     122:             if (!fflg) {
     123:                 fprintf(stderr, "rm: cannot read %s?\n", arg);
     124:                 errcode++;
     125:             }
     126:             return (0);
     127:         }
     128:         if (level == 0)
     129:             append(arg);
     130:         prevname[0] = '\0';
     131:         while ((dp = readdir(dirp)) != NULL) {
     132:             if (dotname(dp->d_name)) {
     133:                 strcpy(prevname, dp->d_name);
     134:                 continue;
     135:             }
     136:             append(dp->d_name);
     137:             closedir(dirp);
     138:             ok = rm(path, level + 1);
     139:             for (cp = pathp; *--cp != '/' && cp > path; )
     140:                 ;
     141:             pathp = cp;
     142:             *cp++ = '\0';
     143:             if ((dirp = opendir(arg)) == NULL) {
     144:                 if (!fflg) {
     145:                     fprintf(stderr, "rm: cannot read %s?\n", arg);
     146:                     errcode++;
     147:                 }
     148:                 break;
     149:             }
     150:             /* pick up where we left off */
     151:             if (prevname[0] != '\0') {
     152:                 while ((dp = readdir(dirp)) != NULL &&
     153:                     strcmp(prevname, dp->d_name) != 0)
     154:                     ;
     155:             }
     156:             /* skip the one we just failed to delete */
     157:             if (!ok) {
     158:                 dp = readdir(dirp);
     159:                 if (dp != NULL && strcmp(cp, dp->d_name)) {
     160:                     fprintf(stderr,
     161:             "rm: internal synchronization error: %s, %s, %s\n",
     162:                         arg, cp, dp->d_name);
     163:                 }
     164:                 strcpy(prevname, dp->d_name);
     165:             }
     166:         }
     167:         closedir(dirp);
     168:         if (level == 0) {
     169:             pathp = path;
     170:             *pathp = '\0';
     171:         }
     172:         if (iflg) {
     173:             printf("rm: remove %s? ", arg);
     174:             if (!yes())
     175:                 return (0);
     176:         }
     177:         if (rmdir(arg) < 0) {
     178:             if (!fflg || iflg) {
     179:                 fprintf(stderr, "rm: %s not removed\n", arg);
     180:                 errcode++;
     181:             }
     182:             return (0);
     183:         }
     184:         return (1);
     185:     }
     186:
     187:     if (iflg) {
     188:         printf("rm: remove %s? ", arg);
     189:         if (!yes())
     190:             return (0);
     191:     } else if (!fflg) {
     192:         if ((buf.st_mode&S_IFMT) != S_IFLNK && access(arg, W_OK) < 0) {
     193:             printf("rm: override protection %o for %s? ",
     194:                 buf.st_mode&0777, arg);
     195:             if (!yes())
     196:                 return (0);
     197:         }
     198:     }
     199:     if (unlink(arg) < 0) {
     200:         if (!fflg || iflg) {
     201:             fprintf(stderr, "rm: %s not removed\n", arg);
     202:             errcode++;
     203:         }
     204:         return (0);
     205:     }
     206:     return (1);
     207: }
     208:
     209: /*
     210:  * boolean: is it "." or ".." ?
     211:  */
     212: dotname(s)
     213:     char *s;
     214: {
     215:     if (s[0] == '.')
     216:         if (s[1] == '.')
     217:             if (s[2] == '\0')
     218:                 return (1);
     219:             else
     220:                 return (0);
     221:         else if (s[1] == '\0')
     222:             return (1);
     223:     return (0);
     224: }
     225:
     226: /*
     227:  * Get a yes/no answer from the user.
     228:  */
     229: yes()
     230: {
     231:     int i, b;
     232:
     233:     i = b = getchar();
     234:     while (b != '\n' && b != EOF)
     235:         b = getchar();
     236:     return (i == 'y');
     237: }
     238:
     239: /*
     240:  * Append 'name' to 'path'.
     241:  */
     242: append(name)
     243:     char *name;
     244: {
     245:     register int n;
     246:
     247:     n = strlen(name);
     248:     if (path == NULL) {
     249:         pathsz = MAXNAMLEN + MAXPATHLEN + 2;
     250:         if ((path = malloc(pathsz)) == NULL) {
     251:             fprintf(stderr, "rm: ran out of memory\n");
     252:             exit(1);
     253:         }
     254:         pathp = path;
     255:     } else if (pathp + n + 2 > path + pathsz) {
     256:         fprintf(stderr, "rm: path name too long: %s\n", path);
     257:         exit(1);
     258:     } else if (pathp != path && pathp[-1] != '/')
     259:         *pathp++ = '/';
     260:     strcpy(pathp, name);
     261:     pathp += n;
     262: }

#### Defined functions

append defined in line 242; used 2 times

- in line 129, 136

dotname defined in line 212; used 2 times

- in line 88, 132

main defined in line 21; never used
rm defined in line 78; used 2 times

- in line 66, 138

yes defined in line 229; used 4 times

- in line 109, 174, 189, 195

#### Defined variables

errcode defined in line 17; used 8 times

- in line 68, 95, 103, 117, 124, 146, 180, 202

fflg defined in line 13; used 11 times

- in line 26, 42, 60, 93, 101, 115, 122, 144, 178, 191, 200

iflg defined in line 14; used 7 times

- in line 27, 46, 107, 172, 178, 187, 200

path defined in line 71; used 9 times

- in line 138-139(2), 169, 248-258(6)

pathp defined in line 72; used 11 times

- in line 139-141(2), 169-170(2), 254-261(7)

pathsz defined in line 73; used 3 times

- in line 249-255(3)

rflg defined in line 15; used 3 times

- in line 28, 51, 100

sccsid defined in line 1; never used

Last modified: 1987-02-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1574 |