home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <dir.h>
- #include <stdlib.h>
- #include <process.h>
- #include "regexp.h"
-
- #define FALSE 0
- #define TRUE 1
- #define MAXREG 10 /* Maximum number -s options allowed */
-
- main (int argc,char *argv[],char *env[])
-
- {
- /* Extern routines */
-
- extern char *optarg;
- extern int optind;
- extern int getopt();
- extern char *cdrom();
- extern char *unzip();
- extern char *unarc();
- extern char *tmpdir();
- extern void createdir();
- extern char *getindex();
- extern void usage();
-
- /* Declarations */
-
- FILE *fp;
- char name[BUFSIZ];
- char line[BUFSIZ];
- char directory[BUFSIZ];
- char description[BUFSIZ];
- char search[BUFSIZ];
- char command[BUFSIZ];
- char todir[BUFSIZ];
- char ext[BUFSIZ];
-
- int c;
- int desc;
- int found;
- int unpack;
- int copy;
- int delete;
- int force;
- int and;
- int expr;
- int prev;
- int batch;
- int extension;
-
- struct regexp *exp[MAXREG];
- int neg[MAXREG];
-
- /* Set the default values */
-
- strcpy (todir,tmpdir());
- strcpy (name,getindex());
- strcpy (search,"");
- strcpy (directory,"");
- strcpy (ext,"*.*");
- desc = TRUE;
- unpack = FALSE;
- copy = FALSE;
- delete = FALSE;
- force = FALSE;
- and = TRUE;
- batch = FALSE;
- extension = FALSE;
- expr = 0;
- prev = '\0';
-
- /* Option handling */
-
- while ((c = getopt(argc, argv, "i:s:t:e:fucdnorgbh?")) != EOF)
- {
-
- switch (c)
- {
- case 'I':
- case 'i':
- strcpy (name,optarg);
- break;
- case 'N':
- case 'n':
- break;
- case 'S':
- case 's':
- strcpy (search,optarg);
-
- /* Every search string is mapped to lower case */
- /* to make search more easily */
-
- strlwr (search);
-
- /* If previous option letter is an 'n' or 'N' */
- /* then this means negate the following regular */
- /* expression */
-
- if (prev == 'n' || prev == 'N')
- {
- neg[expr] = TRUE;
- }
- else
- {
- neg[expr] = FALSE;
- }
-
- /* Skip this regular expression if maximum exceeded */
-
- if (expr > MAXREG - 1)
- {
- printf ("Skipping search string %s more %d regular expressions exceeded\n",optarg,MAXREG);
- }
- else
- {
- /* Compile this regular expression */
- exp[expr] = regcomp(search);
- expr++;
- }
- break;
- case 'F':
- case 'f':
- /* Full path names only used in search */
- desc = FALSE;
- break;
- case 'U':
- case 'u':
- if (copy)
- {
- printf ("Options -u and -c are mutal exclusive\n");
- exit (1);
- }
- unpack = TRUE;
- break;
- case 'C':
- case 'c':
- if (unpack)
- {
- printf ("Options -u and -c are mutual exclusive\n");
- exit (1);
- }
-
- copy = TRUE;
- break;
- case 'T':
- case 't':
- /* Target dir */
- strcpy(todir,optarg);
- break;
- case 'D':
- case 'd':
- /* Wipe target dir */
- delete = TRUE;
- break;
- case 'R':
- case 'r':
- /* Forced wipe */
- force = TRUE;
- break;
- case 'O':
- case 'o':
- /* Match if one of the search options matches */
- /* Default it has to match all search options */
-
- and = FALSE;
- break;
- case 'B':
- case 'b':
- /* Output only the commands but do nothing */
- batch = TRUE;
- break;
- case 'E':
- case 'e':
- /* Filenames to be extracted default all files */
- strcpy(ext,optarg);
- extension = TRUE;
- break;
- case 'h':
- case 'H':
- case '?':
- /* HELP !!!! */
- usage();
- exit (1);
- break;
- default:
- /* ILLEGAL OPTION BUT ANYWAY HELP !!!! */
- usage();
- exit (1);
- break;
- }
-
- prev = c;
- }
- /* -b option in conjuction with -u or -c is useful */
-
- if (batch && !(copy || unpack))
- {
- printf ("-b option is only useful together with -c or -u option \n");
- exit (1);
- }
-
- if (extension && !unpack)
- {
- printf ("-e option can only be used together with -u option\n");
- exit (1);
- }
-
- /* If no search expression is given match everything */
-
- if (expr == 0)
- {
- exp[0] = regcomp ("");
- neg[0] = FALSE;
- expr++;
- }
-
- /* If target directory doesn't exsist create it */
-
- if (!batch && !isdir(todir))
- {
- createdir(todir);
- }
-
- /* If target directory is only the drive letter then use */
- /* force option to wipe it */
-
- if (delete && !force && todir[1] == ':' && todir[2] == '\0')
- {
- printf ("Use -r -d to delete an entire disk\n");
- exit (1);
- }
-
- /* If target directory is the current directory the use */
- /* force option to wipe it */
-
- if (delete && !force && (strcmp(todir,".") == 0))
- {
- printf ("Not purging current directory\n");
- printf ("Use -d -r to remove data in current directory");
- exit (1);
- }
-
- if (delete)
- {
- /* We may wipe target directory clean */
- cleanup (todir);
- }
-
- /* Quit after we have wiped target dir but nothing */
- /* to do afterwards */
-
- if (delete && !unpack && !copy) exit(1);
-
- /* Open index file */
-
- if ((fp = fopen (name,"r")) == (FILE *) NULL)
- {
- printf ("Error opening file %s\n",name);
- exit (1);
- }
-
- /* We use the string name later again so initialise it */
- strcpy (name,"");
-
- /* Read lines from index file */
- while (fgets(line,BUFSIZ,fp) != (char *) NULL)
- {
- /* If entry is directory */
- if (strncmp (line,"Directory",7) == 0)
- {
- /* Scan directory name in line */
-
- sscanf (line,"%*s %s\n",directory);
-
- /* Map directory name to lowercase */
-
- strlwr(directory);
-
- /* Replace every forward slash by a backward slash */
-
- for (c=0 ; c < strlen(directory) ; c++)
- {
- if (directory[c] == '/') directory[c]= '\\';
- }
-
- continue;
- }
-
- /* Skip lines that do not contain any useful information */
-
- if (strncmp (line," Filename Type Length Date Description",15) == 0 ) continue;
- if (strncmp (line,"==============================================",10) == 0 ) continue;
-
- /* And also empty lines */
-
- if (strlen(line) < 2) continue;
-
- /* Map line to lower case and remove newline at end of line */
-
- strlwr(line);
- line[strlen(line)-1] = '\0';
-
- /* We haven't found a thing yet */
-
- found=FALSE;
-
- /* Use only the filenames from the line if description */
- /* is not to be used in search and add full path do filename */
- if (!desc)
- {
- sscanf (line,"%s %*s",name);
- sprintf (line,"%s\\%s%s",cdrom(),directory,name);
- }
-
- /* Flush standard output and stderr */
- /* I noticed some trouble with output redirection */
- /* These lines fix this problem */
-
- fflush(stdout);
- fflush(stderr);
-
-
- if (and)
- {
- /* We have a match if all regular expressions */
- /* match the line */
-
- for (c=0; c < expr ; c++)
- {
- if (neg[c] == TRUE ? regexec(exp[c],line) == 0 : regexec(exp[c],line) != 0)
- {
- found = TRUE;
- }
- else
- {
- found = FALSE;
- break;
- }
- }
- }
- else
- {
- /* We have a match if a single expression matches the line */
-
- for (c=0; c < expr ; c++)
- {
- if (neg[c] == TRUE ? regexec(exp[c],line) == 0 : regexec(exp[c],line) != 0)
- {
- found = TRUE;
- break;
- }
- }
- }
-
- /* If search only print the matching line */
-
- if (found)
- {
- if (!unpack && !copy && !batch) printf ("%s\n",line);
- }
-
- /* Remove description,date and size from line */
-
- if (desc)
- {
- sscanf (line,"%s %*s",name);
- }
-
- if (found && unpack)
- {
- /* Build command line for zip files */
-
- if (strcmp(strrchr(name,'.'),".zip") == 0)
- {
- sprintf (command,"%s %s\\%s%s %s %s",unzip(),cdrom(),directory,name,todir,ext);
- printf ("%s\n",command);
- if (!batch) system (command);
- continue;
- }
-
- /* The same for arc files */
-
- if (strcmp(strrchr(name,'.'),".arc") == 0)
- {
- sprintf (command,"%s %s\\%s%s %s %s",unarc(),cdrom(),directory,name,todir,ext);
- printf ("%s\n",command);
- if (!batch) system (command);
- continue;
- }
-
- /* Copy the rest that matches */
-
- sprintf (command,"copy %s\\%s%s %s",cdrom(),directory,name,todir);
- printf ("%s\n",command);
- if (!batch) system (command);
-
- }
-
- if (found && copy)
- {
- /* Build copy command for matching line */
-
- sprintf (command,"copy %s\\%s%s %s",cdrom(),directory,name,todir);
- printf ("%s\n",command);
- if (!batch) system (command);
- }
- }
-
- fclose (fp);
-
- /* Execute command set by POST environment variable */
- /* if something is copied or unpacked */
- /* Useful for virus scanning the target directory */
-
- if ((getenv("POST") != NULL) && (copy || unpack) && !batch)
- {
- system (getenv("POST"));
- }
-
- }
-
-
-
-