Print this page
3965 find does not support -delete option


  70 #define FTW_SLN         7
  71 #endif
  72 #define LINEBUF_SIZE            LINE_MAX        /* input or output lines */
  73 #define REMOTE_FS               "/etc/dfs/fstypes"
  74 #define N_FSTYPES               20
  75 #define SHELL_MAXARGS           253     /* see doexec() for description */
  76 
  77 /*
  78  * This is the list of operations
  79  * F_USER and F_GROUP are named to avoid conflict with USER and GROUP defined
  80  * in sys/acl.h
  81  */
  82 
  83 enum Command
  84 {
  85         PRINT,
  86         ACL, AMIN, AND, ATIME, CMIN, CPIO, CSIZE, CTIME, DEPTH, EXEC, F_GROUP,
  87         F_GROUPACL, F_USER, F_USERACL, FOLLOW, FSTYPE, INAME, INUM, IPATH,
  88         IREGEX, LINKS, LOCAL, LPAREN, LS, MAXDEPTH, MINDEPTH, MMIN, MOUNT,
  89         MTIME, NAME, NCPIO, NEWER, NOGRP, NOT, NOUSER, OK, OR, PATH, PERM,
  90         PRINT0, PRUNE, REGEX, RPAREN, SIZE, TYPE, VARARGS, XATTR
  91 };
  92 
  93 enum Type
  94 {
  95         Unary, Id, Num, Str, Exec, Cpio, Op
  96 };
  97 
  98 struct Args
  99 {
 100         char            name[10];
 101         enum Command    action;
 102         enum Type       type;
 103 };
 104 
 105 /*
 106  * Except for pathnames, these are the only legal arguments
 107  */
 108 static struct Args commands[] =
 109 {
 110         "!",            NOT,            Op,
 111         "(",            LPAREN,         Unary,
 112         ")",            RPAREN,         Unary,
 113         "-a",           AND,            Op,
 114         "-acl",         ACL,            Unary,
 115         "-amin",        AMIN,           Num,
 116         "-and",         AND,            Op,
 117         "-atime",       ATIME,          Num,
 118         "-cmin",        CMIN,           Num,
 119         "-cpio",        CPIO,           Cpio,
 120         "-ctime",       CTIME,          Num,
 121         "-depth",       DEPTH,          Unary,

 122         "-exec",        EXEC,           Exec,
 123         "-follow",      FOLLOW,         Unary,
 124         "-fstype",      FSTYPE,         Str,
 125         "-group",       F_GROUP,        Num,
 126         "-groupacl",    F_GROUPACL,     Num,
 127         "-iname",       INAME,          Str,
 128         "-inum",        INUM,           Num,
 129         "-ipath",       IPATH,          Str,
 130         "-iregex",      IREGEX,         Str,
 131         "-links",       LINKS,          Num,
 132         "-local",       LOCAL,          Unary,
 133         "-ls",          LS,             Unary,
 134         "-maxdepth",    MAXDEPTH,       Num,
 135         "-mindepth",    MINDEPTH,       Num,
 136         "-mmin",        MMIN,           Num,
 137         "-mount",       MOUNT,          Unary,
 138         "-mtime",       MTIME,          Num,
 139         "-name",        NAME,           Str,
 140         "-ncpio",       NCPIO,          Cpio,
 141         "-newer",       NEWER,          Str,


 187 
 188 
 189 /*
 190  * Prototype variable size arglist buffer
 191  */
 192 
 193 struct Arglist
 194 {
 195         struct Arglist  *next;
 196         char            *end;
 197         char            *nextstr;
 198         char            **firstvar;
 199         char            **nextvar;
 200         char            *arglist[1];
 201 };
 202 
 203 
 204 static int              compile();
 205 static int              execute();
 206 static int              doexec(char *, char **, int *);

 207 static struct Args      *lookup();
 208 static int              ok();
 209 static void             usage(void)     __NORETURN;
 210 static struct Arglist   *varargs();
 211 static int              list();
 212 static char             *getgroup();
 213 static FILE             *cmdopen();
 214 static int              cmdclose();
 215 static char             *getshell();
 216 static void             init_remote_fs();
 217 static char             *getname();
 218 static int              readmode();
 219 static mode_t           getmode();
 220 static char             *gettail();
 221 
 222 
 223 static int walkflags = FTW_CHDIR|FTW_PHYS|FTW_ANYERR|FTW_NOLOOP;
 224 static struct Node      *topnode;
 225 static struct Node      *freenode;      /* next free node we may use later */
 226 static char             *cpio[] = { "cpio", "-o", 0 };


 512                                 goto err;
 513                         if (oldnp->type == Op) {
 514                                 (void) fprintf(stderr,
 515                                     gettext("%s: cannot immediately"
 516                                     " follow an operand with ')'\n"),
 517                                     cmdname);
 518                                 exit(1);
 519                         }
 520                         oldnp->next = 0;
 521                         return (av-argv);
 522 
 523                 case FOLLOW:
 524                         walkflags &= ~FTW_PHYS;
 525                         break;
 526                 case MOUNT:
 527                         walkflags |= FTW_MOUNT;
 528                         break;
 529                 case DEPTH:
 530                         walkflags |= FTW_DEPTH;
 531                         break;





 532 
 533                 case LOCAL:
 534                         np->first.l = 0L;
 535                         np->first.ll = 0LL;
 536                         np->second.i = '+';
 537                         /*
 538                          * Make it compatible to df -l for
 539                          * future enhancement. So, anything
 540                          * that is not remote, then it is
 541                          * local.
 542                          */
 543                         init_remote_fs();
 544                         break;
 545 
 546                 case SIZE:
 547                         if (b[strlen(b)-1] == 'c')
 548                                 np->action = CSIZE;
 549                         /*FALLTHROUGH*/
 550                 case INUM:
 551                         np->first.ll = atoll(b);


 950                                 val = (ll > np->first.ll);
 951                         else if (np->second.i == '-')
 952                                 val = (ll < np->first.ll);
 953                         else
 954                                 val = (ll == np->first.ll);
 955                         break;
 956                 num:
 957                         if (np->second.i == '+')
 958                                 val = (l > np->first.l);
 959                         else if (np->second.i == '-')
 960                                 val = (l < np->first.l);
 961                         else
 962                                 val = (l == np->first.l);
 963                         break;
 964                 case OK:
 965                         val = ok(name, np->first.ap);
 966                         break;
 967                 case EXEC:
 968                         val = doexec(name, np->first.ap, NULL);
 969                         break;



 970 
 971                 case VARARGS: {
 972                         struct Arglist *ap = np->first.vp;
 973                         char *cp;
 974                         cp = ap->nextstr - (strlen(name)+1);
 975                         if (cp >= (char *)(ap->nextvar+3)) {
 976                                 /* there is room just copy the name */
 977                                 val = 1;
 978                                 (void) strcpy(cp, name);
 979                                 *ap->nextvar++ = cp;
 980                                 ap->nextstr = cp;
 981                         } else {
 982                                 /* no more room, exec command */
 983                                 *ap->nextvar++ = name;
 984                                 *ap->nextvar = 0;
 985                                 val = 1;
 986                                 (void) doexec((char *)0, ap->arglist,
 987                                     &exec_exitcode);
 988                                 ap->nextstr = ap->end;
 989                                 ap->nextvar = ap->firstvar;


1301                         if (status)
1302                                 exit_status = 1;
1303                 }
1304                 /* all the invocations have completed */
1305                 exit(exit_status);
1306         }
1307 
1308         if (name && dummyseen) {
1309                 for (av = argv; cp = *av++; ) {
1310                         if (cp == name)
1311                                 av[-1] = dummyarg;
1312                 }
1313         }
1314 
1315         if (r && exitcode != NULL)
1316                 *exitcode = 3; /* use to indicate error in cmd invocation */
1317 
1318         return (!r);
1319 }
1320 





1321 






































1322 /*
1323  *  Table lookup routine
1324  */
1325 static struct Args *
1326 lookup(word)
1327 char *word;
1328 {
1329         struct Args *argp = commands;
1330         int second;
1331         if (word == 0 || *word == 0)
1332                 return (0);
1333         second = word[1];
1334         while (*argp->name) {
1335                 if (second == argp->name[1] && strcmp(word, argp->name) == 0)
1336                         return (argp);
1337                 argp++;
1338         }
1339         return (0);
1340 }
1341 




  70 #define FTW_SLN         7
  71 #endif
  72 #define LINEBUF_SIZE            LINE_MAX        /* input or output lines */
  73 #define REMOTE_FS               "/etc/dfs/fstypes"
  74 #define N_FSTYPES               20
  75 #define SHELL_MAXARGS           253     /* see doexec() for description */
  76 
  77 /*
  78  * This is the list of operations
  79  * F_USER and F_GROUP are named to avoid conflict with USER and GROUP defined
  80  * in sys/acl.h
  81  */
  82 
  83 enum Command
  84 {
  85         PRINT,
  86         ACL, AMIN, AND, ATIME, CMIN, CPIO, CSIZE, CTIME, DEPTH, EXEC, F_GROUP,
  87         F_GROUPACL, F_USER, F_USERACL, FOLLOW, FSTYPE, INAME, INUM, IPATH,
  88         IREGEX, LINKS, LOCAL, LPAREN, LS, MAXDEPTH, MINDEPTH, MMIN, MOUNT,
  89         MTIME, NAME, NCPIO, NEWER, NOGRP, NOT, NOUSER, OK, OR, PATH, PERM,
  90         PRINT0, PRUNE, REGEX, RPAREN, SIZE, TYPE, VARARGS, XATTR, DELETE
  91 };
  92 
  93 enum Type
  94 {
  95         Unary, Id, Num, Str, Exec, Cpio, Op
  96 };
  97 
  98 struct Args
  99 {
 100         char            name[10];
 101         enum Command    action;
 102         enum Type       type;
 103 };
 104 
 105 /*
 106  * Except for pathnames, these are the only legal arguments
 107  */
 108 static struct Args commands[] =
 109 {
 110         "!",            NOT,            Op,
 111         "(",            LPAREN,         Unary,
 112         ")",            RPAREN,         Unary,
 113         "-a",           AND,            Op,
 114         "-acl",         ACL,            Unary,
 115         "-amin",        AMIN,           Num,
 116         "-and",         AND,            Op,
 117         "-atime",       ATIME,          Num,
 118         "-cmin",        CMIN,           Num,
 119         "-cpio",        CPIO,           Cpio,
 120         "-ctime",       CTIME,          Num,
 121         "-depth",       DEPTH,          Unary,
 122         "-delete",      DELETE,         Unary,
 123         "-exec",        EXEC,           Exec,
 124         "-follow",      FOLLOW,         Unary,
 125         "-fstype",      FSTYPE,         Str,
 126         "-group",       F_GROUP,        Num,
 127         "-groupacl",    F_GROUPACL,     Num,
 128         "-iname",       INAME,          Str,
 129         "-inum",        INUM,           Num,
 130         "-ipath",       IPATH,          Str,
 131         "-iregex",      IREGEX,         Str,
 132         "-links",       LINKS,          Num,
 133         "-local",       LOCAL,          Unary,
 134         "-ls",          LS,             Unary,
 135         "-maxdepth",    MAXDEPTH,       Num,
 136         "-mindepth",    MINDEPTH,       Num,
 137         "-mmin",        MMIN,           Num,
 138         "-mount",       MOUNT,          Unary,
 139         "-mtime",       MTIME,          Num,
 140         "-name",        NAME,           Str,
 141         "-ncpio",       NCPIO,          Cpio,
 142         "-newer",       NEWER,          Str,


 188 
 189 
 190 /*
 191  * Prototype variable size arglist buffer
 192  */
 193 
 194 struct Arglist
 195 {
 196         struct Arglist  *next;
 197         char            *end;
 198         char            *nextstr;
 199         char            **firstvar;
 200         char            **nextvar;
 201         char            *arglist[1];
 202 };
 203 
 204 
 205 static int              compile();
 206 static int              execute();
 207 static int              doexec(char *, char **, int *);
 208 static int              dodelete(char *, struct stat *, struct FTW *);
 209 static struct Args      *lookup();
 210 static int              ok();
 211 static void             usage(void)     __NORETURN;
 212 static struct Arglist   *varargs();
 213 static int              list();
 214 static char             *getgroup();
 215 static FILE             *cmdopen();
 216 static int              cmdclose();
 217 static char             *getshell();
 218 static void             init_remote_fs();
 219 static char             *getname();
 220 static int              readmode();
 221 static mode_t           getmode();
 222 static char             *gettail();
 223 
 224 
 225 static int walkflags = FTW_CHDIR|FTW_PHYS|FTW_ANYERR|FTW_NOLOOP;
 226 static struct Node      *topnode;
 227 static struct Node      *freenode;      /* next free node we may use later */
 228 static char             *cpio[] = { "cpio", "-o", 0 };


 514                                 goto err;
 515                         if (oldnp->type == Op) {
 516                                 (void) fprintf(stderr,
 517                                     gettext("%s: cannot immediately"
 518                                     " follow an operand with ')'\n"),
 519                                     cmdname);
 520                                 exit(1);
 521                         }
 522                         oldnp->next = 0;
 523                         return (av-argv);
 524 
 525                 case FOLLOW:
 526                         walkflags &= ~FTW_PHYS;
 527                         break;
 528                 case MOUNT:
 529                         walkflags |= FTW_MOUNT;
 530                         break;
 531                 case DEPTH:
 532                         walkflags |= FTW_DEPTH;
 533                         break;
 534                 case DELETE:
 535                         walkflags |= (FTW_DEPTH | FTW_PHYS);
 536                         walkflags &= ~FTW_CHDIR;
 537                         (*actionp)++;
 538                         break;
 539 
 540                 case LOCAL:
 541                         np->first.l = 0L;
 542                         np->first.ll = 0LL;
 543                         np->second.i = '+';
 544                         /*
 545                          * Make it compatible to df -l for
 546                          * future enhancement. So, anything
 547                          * that is not remote, then it is
 548                          * local.
 549                          */
 550                         init_remote_fs();
 551                         break;
 552 
 553                 case SIZE:
 554                         if (b[strlen(b)-1] == 'c')
 555                                 np->action = CSIZE;
 556                         /*FALLTHROUGH*/
 557                 case INUM:
 558                         np->first.ll = atoll(b);


 957                                 val = (ll > np->first.ll);
 958                         else if (np->second.i == '-')
 959                                 val = (ll < np->first.ll);
 960                         else
 961                                 val = (ll == np->first.ll);
 962                         break;
 963                 num:
 964                         if (np->second.i == '+')
 965                                 val = (l > np->first.l);
 966                         else if (np->second.i == '-')
 967                                 val = (l < np->first.l);
 968                         else
 969                                 val = (l == np->first.l);
 970                         break;
 971                 case OK:
 972                         val = ok(name, np->first.ap);
 973                         break;
 974                 case EXEC:
 975                         val = doexec(name, np->first.ap, NULL);
 976                         break;
 977                 case DELETE:
 978                         val = dodelete(name, statb, state);
 979                         break;
 980 
 981                 case VARARGS: {
 982                         struct Arglist *ap = np->first.vp;
 983                         char *cp;
 984                         cp = ap->nextstr - (strlen(name)+1);
 985                         if (cp >= (char *)(ap->nextvar+3)) {
 986                                 /* there is room just copy the name */
 987                                 val = 1;
 988                                 (void) strcpy(cp, name);
 989                                 *ap->nextvar++ = cp;
 990                                 ap->nextstr = cp;
 991                         } else {
 992                                 /* no more room, exec command */
 993                                 *ap->nextvar++ = name;
 994                                 *ap->nextvar = 0;
 995                                 val = 1;
 996                                 (void) doexec((char *)0, ap->arglist,
 997                                     &exec_exitcode);
 998                                 ap->nextstr = ap->end;
 999                                 ap->nextvar = ap->firstvar;


1311                         if (status)
1312                                 exit_status = 1;
1313                 }
1314                 /* all the invocations have completed */
1315                 exit(exit_status);
1316         }
1317 
1318         if (name && dummyseen) {
1319                 for (av = argv; cp = *av++; ) {
1320                         if (cp == name)
1321                                 av[-1] = dummyarg;
1322                 }
1323         }
1324 
1325         if (r && exitcode != NULL)
1326                 *exitcode = 3; /* use to indicate error in cmd invocation */
1327 
1328         return (!r);
1329 }
1330 
1331 static int
1332 dodelete(char *name, struct stat *statb, struct FTW *state)
1333 {
1334         char *fn;
1335         int rc = 0;
1336 
1337         /* restrict symlinks */
1338         if ((walkflags & FTW_PHYS) == 0) {
1339                 (void) fprintf(stderr,
1340                     gettext("-delete is not allowed when symlinks are "
1341                     "followed.\n"));
1342                 return (1);
1343         }
1344 
1345         fn = name + state->base;
1346         if (strcmp(fn, ".") == 0) {
1347                 /* nothing to do */
1348                 return (1);
1349         }
1350 
1351         if (strchr(fn, '/') != NULL) {
1352                 (void) fprintf(stderr,
1353                     gettext("-delete with relative path is unsafe."));
1354                 return (1);
1355         }
1356 
1357         if (S_ISDIR(statb->st_mode)) {
1358                 /* delete directory */
1359                 rc = rmdir(name);
1360         } else {
1361                 /* delete file */
1362                 rc = unlink(name);
1363         }
1364 
1365         if (rc < 0) {
1366                 /* operation failed */
1367                 (void) fprintf(stderr, gettext("delete failed %s: %s\n"),
1368                     name, strerror(errno));
1369                 return (1);
1370         }
1371 
1372         return (1);
1373 }
1374 
1375 /*
1376  *  Table lookup routine
1377  */
1378 static struct Args *
1379 lookup(word)
1380 char *word;
1381 {
1382         struct Args *argp = commands;
1383         int second;
1384         if (word == 0 || *word == 0)
1385                 return (0);
1386         second = word[1];
1387         while (*argp->name) {
1388                 if (second == argp->name[1] && strcmp(word, argp->name) == 0)
1389                         return (argp);
1390                 argp++;
1391         }
1392         return (0);
1393 }
1394