1 /*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. 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 8.2 (Berkeley) 04/16/94"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 18 #include <err.h> 19 #include <fts.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "find.h" 25 26 static OPTION *option __P((char *)); 27 28 /* NB: the following table must be sorted lexically. */ 29 static OPTION const options[] = { 30 { "!", N_NOT, c_not, O_ZERO }, 31 { "(", N_OPENPAREN, c_openparen, O_ZERO }, 32 { ")", N_CLOSEPAREN, c_closeparen, O_ZERO }, 33 { "-a", N_AND, NULL, O_NONE }, 34 { "-and", N_AND, NULL, O_NONE }, 35 { "-atime", N_ATIME, c_atime, O_ARGV }, 36 { "-ctime", N_CTIME, c_ctime, O_ARGV }, 37 { "-depth", N_DEPTH, c_depth, O_ZERO }, 38 { "-exec", N_EXEC, c_exec, O_ARGVP }, 39 { "-follow", N_FOLLOW, c_follow, O_ZERO }, 40 { "-fstype", N_FSTYPE, c_fstype, O_ARGV }, 41 { "-group", N_GROUP, c_group, O_ARGV }, 42 { "-inum", N_INUM, c_inum, O_ARGV }, 43 { "-links", N_LINKS, c_links, O_ARGV }, 44 { "-ls", N_LS, c_ls, O_ZERO }, 45 { "-mtime", N_MTIME, c_mtime, O_ARGV }, 46 { "-name", N_NAME, c_name, O_ARGV }, 47 { "-newer", N_NEWER, c_newer, O_ARGV }, 48 { "-nogroup", N_NOGROUP, c_nogroup, O_ZERO }, 49 { "-nouser", N_NOUSER, c_nouser, O_ZERO }, 50 { "-o", N_OR, c_or, O_ZERO }, 51 { "-ok", N_OK, c_exec, O_ARGVP }, 52 { "-or", N_OR, c_or, O_ZERO }, 53 { "-path", N_PATH, c_path, O_ARGV }, 54 { "-perm", N_PERM, c_perm, O_ARGV }, 55 { "-print", N_PRINT, c_print, O_ZERO }, 56 { "-prune", N_PRUNE, c_prune, O_ZERO }, 57 { "-size", N_SIZE, c_size, O_ARGV }, 58 { "-type", N_TYPE, c_type, O_ARGV }, 59 { "-user", N_USER, c_user, O_ARGV }, 60 { "-xdev", N_XDEV, c_xdev, O_ZERO }, 61 }; 62 63 /* 64 * find_create -- 65 * create a node corresponding to a command line argument. 66 * 67 * TODO: 68 * add create/process function pointers to node, so we can skip 69 * this switch stuff. 70 */ 71 PLAN * 72 find_create(argvp) 73 char ***argvp; 74 { 75 register OPTION *p; 76 PLAN *new; 77 char **argv; 78 79 argv = *argvp; 80 81 if ((p = option(*argv)) == NULL) 82 errx(1, "%s: unknown option", *argv); 83 ++argv; 84 if (p->flags & (O_ARGV|O_ARGVP) && !*argv) 85 errx(1, "%s: requires additional arguments", *--argv); 86 87 switch(p->flags) { 88 case O_NONE: 89 new = NULL; 90 break; 91 case O_ZERO: 92 new = (p->create)(); 93 break; 94 case O_ARGV: 95 new = (p->create)(*argv++); 96 break; 97 case O_ARGVP: 98 new = (p->create)(&argv, p->token == N_OK); 99 break; 100 default: 101 abort(); 102 } 103 *argvp = argv; 104 return (new); 105 } 106 107 static OPTION * 108 option(name) 109 char *name; 110 { 111 OPTION tmp; 112 int typecompare __P((const void *, const void *)); 113 114 tmp.name = name; 115 return ((OPTION *)bsearch(&tmp, options, 116 sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare)); 117 } 118 119 int 120 typecompare(a, b) 121 const void *a, *b; 122 { 123 return (strcmp(((OPTION *)a)->name, ((OPTION *)b)->name)); 124 } 125