/* glob.c file filter for grep.*/ /* Copyright 2000 Edscott Wilson Garcia This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*****************************************************************/ #include "globber.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_SNPRINTF # include "snprintf.h" #endif #ifdef DMALLOC # include "dmalloc.h" #endif /** tripas */ #define VERSION_NAME "\nglob 0.5.0\n\nCopyright 2000-2001 Edscott Wilson Garcia\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" #define GREP "grep" static void *object=NULL; static int initial; static int terminated = 0; static char *token; static int options=0,type=0; static long size=0; static long month_t=0; static long unsigned day_t=0; static long unsigned hour_t=0; static long unsigned min_t=0; #define GLOBRUN_PID 0x01 #define GLOBRUN_COUNT 0x02 #define GLOBRUN_FILTERED 0x04 #define GLOBRUN_IGNORE_CASE 0x08 #define GLOBRUN_REG_EXP 0x10 #define GLOBRUN_INVERT 0x20 /*#define GLOBRUN_WHATEVER 0x40*/ #define GLOBRUN_WORDS_ONLY 0x80 #define GLOBRUN_LINES_ONLY 0x100 #define GLOBRUN_ZERO_BYTE 0x200 #define GLOBRUN_NOBINARIES 0x400 #define GLOBRUN_RECURSIVE 0x800 #define GLOBRUN_VERBOSE 0x1000 #define GLOBRUN_XDEV 0x2000 #define MAX_ARG 25 static int display (char *input) { if (terminated) return terminated; /* die quietly and quickly */ printf ("%s\n", input); if (time (NULL) - initial > 3) { fflush (NULL); initial = time (NULL); } return terminated; } static int grep (char *file) { static char *arguments[MAX_ARG]; int status = 0; if (terminated) return terminated; /* die quietly and quickly */ arguments[status++] = "grep"; arguments[status++] = "-d"; arguments[status++] = "skip"; arguments[status++] = "-H"; if (options & GLOBRUN_NOBINARIES) arguments[status++] = "-I"; if (options & GLOBRUN_IGNORE_CASE) arguments[status++] = "-i"; if (options & GLOBRUN_WORDS_ONLY) arguments[status++] = "-w"; if (options & GLOBRUN_LINES_ONLY) arguments[status++] = "-x"; if (options & GLOBRUN_ZERO_BYTE) arguments[status++] = "-Z"; if ((options & GLOBRUN_COUNT) && (options & GLOBRUN_INVERT)) { arguments[status++] = "-c"; arguments[status++] = "-v"; } if ((options & GLOBRUN_COUNT) && !(options & GLOBRUN_INVERT)) { arguments[status++] = "-c"; } if (!(options & GLOBRUN_COUNT) && (options & GLOBRUN_INVERT)) { arguments[status++] = "-L"; } if (!(options & GLOBRUN_COUNT) && !(options & GLOBRUN_INVERT)) { arguments[status++] = "-l"; } if (options & GLOBRUN_REG_EXP) arguments[status++] = "-E"; else arguments[status++] = "-e"; arguments[status++] = token; arguments[status++] = file; arguments[status++] = (char *) 0; if (options & GLOBRUN_VERBOSE) { int i; for (i = 0; i < status; i++) printf ("%s ", arguments[i]); printf ("\n"); } if (fork () == 0){ execvp (GREP, arguments); fprintf(stderr,"%s not found in path!\n",GREP); exit(1); } wait (&status); /*fflush(NULL); */ return terminated; } static char *message[] = { " [-vVPrMACaiIyLcwxZ] [-fpotkhsmudgeE (option)] path \n\n", "options: \n" " [-r] [-v] [-d ddd] [-m mmm] [-f filter] [-s (+/-)size]\n", " [-t type] [-p perm] [grep options...] \n", "-v = verbose\n", "-V = print version number information\n", "-a = stay on a single filesystem.\n", "-P = print process id (capital P)\n", "-f filter = file filter (enclosed in quotes if regexp *,? or\n", " [] is used)\n", "-r = recursive\n", "-s +kbytes = size greater than kbytes KBYTES\n", "-s -kbytes = size less than kbytes KBYTES\n", "-p perm = perm is either suid | exe\n", "-o octal_mode = octal mode is the file mode in octal notation\n", "-t type = any | reg | dir | sym | sock | blk | chr | fifo\n", " (any, regular, directory, symlink, socket, blk_dev,\n", " chr_dev, fifo: any is the default.)\n", " * Time options must be used with either -M, -C, or -A.\n" "-k min = file time in the previous (int) min minutes (either -M -C -A)\n", "-h hhh = file time in the previous (int) hh hours (either -M -C -A)\n", "-d ddd = file time in the previous (int) dd days (either -M -C -A)\n", "-m mmm = file time in the previous (int) mm months (either -M -C -A)\n", "-M = use mtime for file (modification time: mknod, truncate,\n", " utime,write \n", "-A = use atime for file (access time: exec, mknod, pipe,\n", " utime, read) \n", "-C = use ctime for file (change time: setting inode information\n", " i.e., owner, group, link count, mode, etc.) \n", "-u user-id = only files matching numeric user-id\n", "-g group-id = only files matching numeric group-id\n", "-Z = Output a zero byte (the ASCII NUL character)\n", " instead of the character that normally follows a\n", " file name (never tested option, if you do, email me)\n", "\n", "**specifying these option will be used in content search (grep):\n", "-e string = containing string (if *,? or [], use quotes)\n", "-E regexp = containing regexp: (use quotes amigo). \n", "-i = ignore case (for search string -c)\n", "-I = do not search into binary files\n", "-y = same as -i (obsolete)\n", "-L = print the name of each input file from which *no*\n", " output would normally have been printed.\n", "-c = only print a count of matching lines for each input\n", " file.\n", "-w = Select only those lines containing matches that\n", " form whole words. Word-constituent characters are\n", " letters, digits, and the underscore.\n", "-x = Select only those matches that exactly match the\n", " whole line.\n", "\n", NULL }; void finish (int sig) { /*printf("\n****\nglob terminated by signal\n****\n"); */ terminated = 1; fflush (NULL); } void halt (int sig) { fflush (NULL); globber_destroy(object); exit (1); } #define CHECK_ARG if (argc <= i) goto error; int main (int argc, char **argv) { int i,timetype=0; char *filter = NULL, globbered = 0; int (*operate) (char *) = display; initial = time (NULL); /* initializations */ signal (SIGHUP, halt); signal (SIGSEGV, finish); signal (SIGKILL, finish); signal (SIGTERM, finish); if (argc < 2) { error: fprintf (stdout, "use: %s ", argv[0]); i = 0; while (message[i]) fprintf (stdout,"%s", message[i++]); exit (1); } object=globber_create(); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { /* options for the globber : *****************/ if (strstr (argv[i], "M") != NULL) { timetype=1; glob_set_options(object,GLOBBER_MTIME); continue; } if (strstr (argv[i], "A") != NULL) { timetype=1; glob_set_options(object,GLOBBER_ATIME); continue; } if (strstr (argv[i], "C") != NULL) { timetype=1; glob_set_options(object,GLOBBER_CTIME); continue; } if (strstr (argv[i], "a") != NULL) { glob_set_options(object,GLOBBER_XDEV); options |= GLOBRUN_XDEV; continue; } if (strstr (argv[i], "v") != NULL) { glob_set_options(object,GLOBBER_VERBOSE); options |= GLOBRUN_VERBOSE; continue; } if (strstr (argv[i], "r") != NULL) { glob_set_options(object,GLOBBER_RECURSIVE); options |= GLOBRUN_RECURSIVE; continue; } if (strstr (argv[i], "u") != NULL) { i++; CHECK_ARG; glob_set_user(object,atol(argv[i])); continue; } if (strstr (argv[i], "g") != NULL) { i++; CHECK_ARG; glob_set_group(object,atol(argv[i])); continue; } if (strstr (argv[i], "t") != NULL) { i++; type &= 07777; CHECK_ARG; /*if (strcmp (argv[i], "any") == 0) type &= 07777;*/ if (strcmp (argv[i], "reg") == 0) type |= S_IFREG; if (strcmp (argv[i], "dir") == 0) type |= S_IFDIR; if (strcmp (argv[i], "sym") == 0) type |= S_IFLNK; if (strcmp (argv[i], "sock") == 0)type |= S_IFSOCK; if (strcmp (argv[i], "blk") == 0) type |= S_IFBLK; if (strcmp (argv[i], "chr") == 0) type |= S_IFCHR; if (strcmp (argv[i], "fifo") == 0)type |= S_IFIFO; if (strcmp (argv[i], "any") != 0) { glob_set_options(object,GLOBBER_TYPE); glob_set_type(object,type); } continue; } if (strstr (argv[i], "p") != NULL) { i++; /*type &= S_IFMT;*/ CHECK_ARG; if (strcmp (argv[i], "suid") == 0) type |= S_ISUID; if (strcmp (argv[i], "exe") == 0) type |= S_IXUSR; glob_set_options(object,GLOBBER_PERM); glob_set_type(object,type); continue; } if (strstr (argv[i], "o") != NULL) { int valor; i++; type &= S_IFMT; CHECK_ARG; sscanf(argv[i],"%o",&valor); type |= (07777&valor); glob_set_options(object,GLOBBER_PERM); glob_set_type(object,type); continue; } if (strstr (argv[i], "s") != NULL) { i++; CHECK_ARG; size = atol (argv[i]); if (size < 0) glob_set_sizeL(object,-size*1024); else glob_set_sizeG(object,size*1024); continue; } if (strstr (argv[i], "k") != NULL) { i++; CHECK_ARG; min_t = atol (argv[i]); glob_set_time(object,month_t,day_t,hour_t,min_t); continue; } if (strstr (argv[i], "h") != NULL) { i++; CHECK_ARG; hour_t = atol (argv[i]); glob_set_time(object,month_t,day_t,hour_t,min_t); continue; } if (strstr (argv[i], "d") != NULL) { i++; CHECK_ARG; day_t = atol (argv[i]); glob_set_time(object,month_t,day_t,hour_t,min_t); continue; } if (strstr (argv[i], "m") != NULL) { CHECK_ARG; month_t = atol (argv[i]); glob_set_time(object,month_t,day_t,hour_t,min_t); continue; } if (strstr (argv[i], "f") != NULL) { options |= GLOBRUN_FILTERED; i++; CHECK_ARG; filter = argv[i]; if (options & GLOBRUN_VERBOSE) fprintf (stderr, "filtering %s\n", filter); continue; } /* options for grep : *******************/ if (strstr (argv[i], "I") != NULL) { options |= GLOBRUN_NOBINARIES; continue; } if ((strstr (argv[i], "i") != NULL)||(strstr (argv[i], "y") != NULL)) { options |= GLOBRUN_IGNORE_CASE; continue; } if (strstr (argv[i], "L") != NULL) { options |= GLOBRUN_INVERT; continue; } if (strstr (argv[i], "c") != NULL) { options |= GLOBRUN_COUNT; continue; } if (strstr (argv[i], "w") != NULL) { options |= GLOBRUN_WORDS_ONLY; continue; } if (strstr (argv[i], "x") != NULL) { options |= GLOBRUN_LINES_ONLY; continue; } if (strstr (argv[i], "Z") != NULL) { options |= GLOBRUN_ZERO_BYTE; continue; } if (strstr (argv[i], "P") != NULL) { options |= GLOBRUN_PID; printf ("PID=%d\n", (int) getpid ()); fflush (NULL); continue; } if (strstr (argv[i], "E") != NULL) { i++; CHECK_ARG; token = argv[i]; operate = grep; options |= GLOBRUN_REG_EXP; continue; } if (strstr (argv[i], "e") != NULL) { i++; CHECK_ARG; token = argv[i]; operate = grep; options |= GLOBRUN_REG_EXP; options ^= GLOBRUN_REG_EXP; /* turn off extended regexp */ continue; } if (strstr (argv[i], "V") != NULL) { printf ("%s", VERSION_NAME); return 0; } fprintf(stdout,"unknown argument: %s\nuse -h for help.\n",argv[i]); exit(1); } if (((min_t)||(hour_t)||(day_t)||(month_t))&& !timetype) glob_set_options(object,GLOBBER_MTIME); terminated = globber (object,argv[i], operate, filter); globbered = 1; } /* end of argument processing */ if (!globbered) { fprintf (stderr, "must specify path\n"); goto error; } /* if (terminated) printf("glob run was terminated.\n");*/ if (!terminated) { /* die quietly and quickly */ if (options & GLOBRUN_PID) printf ("GLOB DONE=%d\n", (int) getpid ()); } fflush (NULL); globber_destroy(object); exit (0); }