1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Cimarron D. Taylor of the University of California, Berkeley. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)option.c 5.5 (Berkeley) 03/09/91"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <fts.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include "find.h" 22 23 typedef struct _option { 24 char *name; /* option name */ 25 int token; /* token value */ 26 PLAN *(*create)(); /* create function */ 27 #define O_NONE 0x01 /* no call required */ 28 #define O_ZERO 0x02 /* pass: nothing */ 29 #define O_ARGV 0x04 /* pass: argv, increment argv */ 30 #define O_ARGVP 0x08 /* pass: *argv, T_OK || T_EXEC */ 31 #define O_MASK 0x0f /* mask of op bits */ 32 #define O_OLD 0x10 /* deprecated syntax */ 33 #define O_NEW 0x20 /* new syntax */ 34 int flags; 35 } OPTION; 36 37 PLAN *c_atime(), *c_ctime(), *c_depth(), *c_exec(), *c_follow(), 38 *c_fstype(), *c_group(), *c_inum(), *c_links(), *c_ls(), 39 *c_mtime(), *c_name(), *c_newer(), *c_nogroup(), *c_nouser(), 40 *c_perm(), *c_print(), *c_prune(), *c_size(), *c_type(), 41 *c_user(), *c_xdev(), *c_openparen(), *c_closeparen(), *c_not(), 42 *c_or(); 43 44 OPTION options[] = { 45 "!", T_NOT, c_not, O_ZERO, 46 "(", T_OPENPAREN, c_openparen, O_ZERO, 47 ")", T_CLOSEPAREN, c_closeparen, O_ZERO, 48 "a", T_AND, NULL, O_NONE|O_OLD, 49 "and", T_AND, NULL, O_NONE|O_NEW, 50 "atime", T_ATIME, c_atime, O_ARGV, 51 "ctime", T_CTIME, c_ctime, O_ARGV, 52 "depth", T_DEPTH, c_depth, O_ZERO|O_OLD, 53 "exec", T_EXEC, c_exec, O_ARGVP, 54 "follow", T_FOLLOW, c_follow, O_ZERO|O_OLD, 55 "fstype", T_FSTYPE, c_fstype, O_ARGV, 56 "group", T_GROUP, c_group, O_ARGV, 57 "inum", T_INUM, c_inum, O_ARGV, 58 "links", T_LINKS, c_links, O_ARGV, 59 "ls", T_LS, c_ls, O_ZERO, 60 "mtime", T_MTIME, c_mtime, O_ARGV, 61 "name", T_NAME, c_name, O_ARGV, 62 "newer", T_NEWER, c_newer, O_ARGV, 63 "nogroup", T_NOGROUP, c_nogroup, O_ZERO, 64 "nouser", T_NOUSER, c_nouser, O_ZERO, 65 "o", T_OR, c_or, O_ZERO|O_OLD, 66 "ok", T_OK, c_exec, O_ARGVP, 67 "or", T_OR, c_or, O_ZERO|O_NEW, 68 "perm", T_PERM, c_perm, O_ARGV, 69 "print", T_PRINT, c_print, O_ZERO, 70 "prune", T_PRUNE, c_prune, O_ZERO, 71 "size", T_SIZE, c_size, O_ARGV, 72 "type", T_TYPE, c_type, O_ARGV, 73 "user", T_USER, c_user, O_ARGV, 74 "xdev", T_XDEV, c_xdev, O_ZERO|O_OLD, 75 { NULL }, 76 }; 77 78 /* 79 * find_create -- 80 * create a node corresponding to a command line argument. 81 * 82 * TODO: 83 * add create/process function pointers to node, so we can skip 84 * this switch stuff. 85 */ 86 PLAN * 87 find_create(argvp) 88 char ***argvp; 89 { 90 register OPTION *p; 91 OPTION tmp; 92 PLAN *new; 93 char **argv; 94 int typecompare(); 95 96 argv = *argvp; 97 tmp.name = *argv++; 98 99 /* strip off any leading dash */ 100 if (*tmp.name == '-') 101 ++tmp.name; 102 103 p = (OPTION *)bsearch(&tmp, options, sizeof(options)/sizeof(OPTION), 104 sizeof(OPTION), typecompare); 105 if (!p || isdeprecated && p->flags&O_NEW || 106 !isdeprecated && p->flags&O_OLD) { 107 (void)fprintf(stderr, "find: unknown option %s.\n", *--argv); 108 exit(1); 109 } 110 if (p->flags & (O_ARGV|O_ARGVP) && !*argv) { 111 (void)fprintf(stderr, 112 "find: %s requires additional arguments.\n", *--argv); 113 exit(1); 114 } 115 116 switch(p->flags&O_MASK) { 117 case O_NONE: 118 new = NULL; 119 break; 120 case O_ZERO: 121 new = (p->create)(); 122 break; 123 case O_ARGV: 124 new = (p->create)(*argv++); 125 break; 126 case O_ARGVP: 127 new = (p->create)(&argv, p->token == T_OK); 128 break; 129 } 130 *argvp = argv; 131 return(new); 132 } 133 134 typecompare(a, b) 135 OPTION *a, *b; 136 { 137 return(strcmp(a->name, b->name)); 138 } 139