home *** CD-ROM | disk | FTP | other *** search
- /* FF.C */
- /* */
- /* See FF.DOC for syntax and options. */
- /* */
- /* Language: Microsoft C, version 4.0 (small memory model) */
- /* */
- /* External files needed: DOSTYPE.H */
- /* */
- /* External functions */
- /* From FINDENTR.C - findentr(), findnext() */
- /* DTA.C - get_DTA(). set_DTA() */
- /* */
- /* Linking: LINK ff+findentr+dta */
- /* FINDENTR.OBJ and DTA.OBJ must be present. */
- /* */
- /* Written by: Bill Mayne */
- /* 9707 Lawndale Dr. */
- /* Silver Spring, MD 20901 */
- /* */
- /* Date written: May 19, 1987 */
- /* Revised: June 30, 1987 to support selection by file size and date. */
- /* July 15, 1987 (1) default .ext of ".*" added. */
- /* (2) Command summary displayed if no arguments given. */
- /* */
- #include <stdio.h>
- #include <memory.h>
- #include <dos.h>
- #include <string.h>
- #include <conio.h>
- #include <ctype.h>
- #include "dostype.h"
-
- extern void get_DTA(unsigned *,unsigned *),
- set_DTA(unsigned, unsigned);
- extern int findentr(struct DTA_STRUCT *, char *, int),
- findnext(struct DTA_STRUCT *);
-
- int s_attr=0; /* permitted attributes (use for H,S,D) */
- int m_attr=0; /* excluded attributes (use for A,R) */
- int r_attr=0; /* required attributes (any) */
- int r_levels=9999; /* levels to search (use to restrict) */
- unsigned long maxsize=~(0L);
- unsigned long minsize=0;
- int cur_level=1;
-
- /* command summary to display when no arguments */
- char *cmd_summary[]=
- {
- "FF.EXE - File Find utility\n",
- "Syntax: FF [/options] [drive:][path\\]filename[.ext]",
- " or: FF [drive:][path\\]filename[.ext] [/options]\n",
- "Wildcards allowed in filename.ext.",
- "Search starts at specified (or default root) directory.",
- "Interrupt with CTRL-C at any time.\n",
- "Options:",
- "/I - Include attributes. Use to specify D, H, or S.",
- "/X - Exclude attributes. Use for A and R.",
- "/R - Required attributes - any of A, D, R, H, or S.",
- "/Yfrom:to - date/time range to select files.",
- " \"from\" and \"to\" are in the form \"YYMMDDhhmm\".",
- "/Smin:max - size range of file to select",
- "/n - where n is a decimal integer (without sign) limits the depth of the search.",
- "/D - directory format display.\n",
- "See FF.DOC for details."
- };
-
- /* date and time range of files to select */
- union
- {
- struct FCB_DATE field;
- unsigned long date_time;
- } start, enddt;
-
- #include <main.h>
- {
- char st_dir[128];
- char hold_name[128], *namepart;
- char *p;
- unsigned yy,mm,dd,hh,min;
- int i, i_incr, j, disp_dirs=0, disp_cmds=0;
-
- /* If no arguments display command summary */
- if (argc<2)
- {
- j=sizeof(cmd_summary)/sizeof(cmd_summary[0]);
- for (i=0; i<j; puts(cmd_summary[i++]));
- exit(0);
- }
-
- /* initialize date/time range to all possible values */
- start.date_time=0;
- enddt.date_time=~(0L);
- if (*argv[i=argc-1]=='/') i_incr=-1;
- else {i=1; i_incr=1;}
- while (i<argc && i>0 && *argv[i]=='/')
- {
- strupr(argv[i]);
- switch (argv[i][1])
- {
- case 'Y':
- {
- yy=mm=dd=hh=min=0;
- sscanf(argv[i]+2,
- "%2d%2d%2d%2d%2d:",
- &yy,&mm,&dd,&hh,&min);
- yy-=80;
- start.field.date.year=yy;
- start.field.date.month=mm;
- start.field.date.day=dd;
- start.field.time.hours=hh;
- start.field.time.minutes=min;
- if (p=strchr(argv[i]+2,','))
- {
- yy=mm=dd=hh=mm=~0;
- sscanf(p+1,
- "%2d%2d%2d%2d%2d/",
- &yy,&mm,&dd,&hh,&min);
- yy-=80;
- enddt.field.date.year=yy;
- enddt.field.date.month=mm;
- enddt.field.date.day=dd;
- enddt.field.time.hours=hh;
- enddt.field.time.minutes=min;
- }
- }
- break;
- case 'D':
- disp_dirs=1;
- break;
- case 'I':
- for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
- {
- switch (argv[i][j])
- {
- case 'A': s_attr|=ARCHIVE; break;
- case 'H': s_attr|=HIDDEN; break;
- case 'S': s_attr|=SYSTEM; break;
- case 'D': s_attr|=DIRECTORY; break;
- case 'R': s_attr|=READONLY; break;
- default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
- }
- }
- break;
- case 'R':
- for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
- {
- switch (argv[i][j])
- {
- case 'A': r_attr|=ARCHIVE; break;
- case 'H': r_attr|=HIDDEN; break;
- case 'S': r_attr|=SYSTEM; break;
- case 'D': r_attr|=DIRECTORY; break;
- case 'R': r_attr|=READONLY; break;
- default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
- }
- }
- break;
- case 'X':
- for (j=2; argv[i][j] && argv[i][j]!='/'; ++j)
- {
- switch (argv[i][j])
- {
- case 'A': m_attr|=ARCHIVE; break;
- case 'H': m_attr|=HIDDEN; break;
- case 'S': m_attr|=SYSTEM; break;
- case 'D': m_attr|=DIRECTORY; break;
- case 'R': m_attr|=READONLY; break;
- default: printf("Invalid attribute '%c' ignored.\n",argv[i][j]);
- }
- }
- break;
- case 'S':
- minsize=atol(argv[i]+2);
- {
- char *p=strchr(argv[i]+2,':');
- if (p++)
- if (isdigit(*p)) maxsize=atol(p);
- else
- fputs("WARNING: Max file size missing or invalid\n",stderr);
- else;
- }
- break;
- default:
- if (isdigit(argv[i][1]) && argv[i][1]>'0')
- r_levels=atoi(argv[i]+1);
- else
- fprintf(stderr,"Invalid option %s ignored\n",argv[i]);
- }
- if ((argv[i]=strchr(argv[i]+1,'/'))==NULL) i+=i_incr;
- }
- if (i==0 || i==argc)
- {
- i=0;
- argv[0]=".\\*.*";
- }
- strupr(argv[i]);
- j=strlen(argv[i])-1;
- while (j>=0 && argv[i][j]!='\\' && argv[i][j]!=':') --j;
- if (j>=0)
- {
- if (argv[i][j]==':')
- {
- st_dir[j+1]='\\';
- st_dir[j+2]='\0';
- }
- else
- st_dir[j+1]='\0';
- namepart=argv[i]+j+1;
- while (j>=0)
- {
- st_dir[j]=argv[i][j];
- --j;
- }
- }
- else
- {
- st_dir[0]='\\';
- st_dir[1]='\0';
- namepart=argv[i];
- }
- strcpy(hold_name,namepart);
- if (strchr(hold_name,'.')==NULL) strcat(hold_name,".*");
- s_attr|=r_attr;
- trav(st_dir,hold_name,disp_dirs);
- }
-
- trav(st_dir,matchname,display_dirs)
- char st_dir[];
- char matchname[];
- int display_dirs;
- {
- char start_directory[128];
- char matchname_buf[128];
- struct DTA_STRUCT DTA, far *FP_DTA=&DTA;
- unsigned save_DTA_SEG, save_DTA_OFF;
- int i;
-
- kbhit(); /* allow CTRL-C interrupt even if break is off */
- strcpy(start_directory,st_dir);
- strcpy(matchname_buf,start_directory);
- strcat (matchname_buf,matchname);
-
- get_DTA(&save_DTA_SEG,&save_DTA_OFF);
- set_DTA(FP_SEG(FP_DTA),FP_OFF(FP_DTA));
- if (findentr(NULL,matchname_buf,s_attr)==0)
- {
- int first=1;
- int more=0; /* in this case 0 means something was found */
- while (more==0)
- {
- if ((DTA.timestamp.date_time>=start.date_time) &&
- (DTA.timestamp.date_time<=enddt.date_time) &&
- (DTA.attr & m_attr)==0 &&
- (DTA.attr & r_attr)==r_attr &&
- (DTA.size <= maxsize) &&
- (DTA.size >= minsize))
- {
- if (display_dirs)
- {
- if (first) {first=0; printf("%s\n",start_directory);}
- display_entry(&DTA,0);
- }
- else display_entry(&DTA,1,start_directory);
- }
- more=findnext(NULL);
- }
- }
- set_DTA(save_DTA_SEG,save_DTA_OFF);
-
- if (cur_level<r_levels)
- {
- ++cur_level;
- /* go looking for more directories */
- strcpy(matchname_buf,start_directory);
- strcat(matchname_buf,"*");
- if (findentr(&DTA,matchname_buf,DIRECTORY)==0)
- do
- if ((DIRECTORY & DTA.attr) && *DTA.name!='.')
- {
- /* recursively traverse subdirectory */
- strcpy(matchname_buf,start_directory);
- strcat(matchname_buf,DTA.name);
- strcat(matchname_buf,"\\");
- trav(matchname_buf,matchname,display_dirs);
- }
- while (findnext(&DTA)==0);
- --cur_level;
- }
- }
-
- display_entry(DTA,disp_directory,directory)
- struct DTA_STRUCT *DTA;
- int disp_directory;
- char directory[];
- {
- int dir_len, name_len, size_col, yy, mm, dd, hh, min;
- char ampm;
- if (disp_directory)
- {
- printf("%s%n",directory,&dir_len);
- size_col=32;
- }
- else
- {
- putchar(' ');
- dir_len=0;
- size_col=12;
- }
- printf("%s%n",(*DTA).name,&name_len);
- name_len+=dir_len;
- name_len=size_col-name_len;
- while (name_len>0) putchar(' '), --name_len;
- printf("%7lu",(*DTA).size);
- yy=(*DTA).timestamp.field.date.year;
- yy+=80;
- yy%=100;
- dd=(*DTA).timestamp.field.date.day;
- mm=(*DTA).timestamp.field.date.month;
- hh=(*DTA).timestamp.field.time.hours;
- min=(*DTA).timestamp.field.time.minutes;
- if (hh<1)
- {
- hh=12;
- ampm='a';
- }
- else if (hh>=12)
- {
- ampm='p';
- if (hh>12) hh-=12;
- }
- else
- ampm='a';
- printf(" %2d-%0.2d-%0.2d %2d:%0.2d%c",mm,dd,yy,hh,min,ampm);
- putchar(' ');
- if ((*DTA).attr & ARCHIVE) putchar('A');
- if ((*DTA).attr & DIRECTORY) putchar('D');
- if ((*DTA).attr & SYSTEM) putchar('S');
- if ((*DTA).attr & HIDDEN) putchar('H');
- if ((*DTA).attr & READONLY) putchar('R');
- putchar('\n');
- }