// This function searches files for a string. // written for MS-C 5.10 #include "stdio.h" #include "dos.h" #include "stdlib.h" #include "process.h" #include "string.h" #include "fcntl.h" #include "ctype.h" #define ERROR -2 #define OK 0 #define EOFF -1 #define ALLDONE 1 #define FALSE 1 #define TRUE 0 #define FILE_LINE_LENGTH 256 char sfilename[40]; FILE *pf; // file pointer struct f_list { char name[80]; // file name struct f_list *next; }; char lchr; char *pline; char *pbuf; int filstat,buflen; char test_string[FILE_LINE_LENGTH+1]; char com; char tmp; char *p; // working string char *pfbuf; char pattern[FILE_LINE_LENGTH+1]; // pattern string pointer unsigned int patlen; // pattern length int line_count; int scr_line_count; int pnum,match_cnt; int match_stat; int status; struct f_list *scanfile; // file list structure. struct f_list *file_list; // pointer to file list. void main(argc,argv) int argc; char *argv[]; { char *s; char *ptmp; char listcom[80]; char execcom[80]; // file to execute if pattern found. int i; int nonopt; int argnum; int entflg; int caseflg; int flistflg; argnum = 1; nonopt = 1; caseflg = FALSE; flistflg = FALSE; strcpy(execcom,"list"); // Default execute is list.exe. // Parse the command line arguments. while(argnum < argc) { ptmp = argv[argnum]; if(*ptmp == '-') { ptmp++; switch (*ptmp) { case 'c': // case sensitive search (-c). case 'C': caseflg = TRUE; break; case 'n': // list file names with match only (-n). case 'N': flistflg = TRUE; break; case 'e': // user specified file to execute case 'E': // if match found (-e). i = 0; ptmp++; while((*ptmp != '\0') && (*ptmp != '\t') && (*ptmp != ' ')) { execcom[i] = *ptmp; ptmp++; i++; } execcom[i] = '\0'; break; case 'h': // display help information (-h) case 'H': // default: // show help if any error on command line. entflg = ERROR; break; } } else { switch(nonopt) { case 1: strcpy(pattern,ptmp); // search pattern string. nonopt++; break; case 2: strcpy(sfilename,ptmp); // file spec. nonopt++; break; default: entflg = ERROR; break; } } argnum++; } if(entflg == ERROR) { printf("SFIND is a string search utility that will search a file\n"); printf(" or files for a string. The command syntax is:\n\n"); printf(" SFIND search_string [file_name] [-C] [-N] [-Efname]\n\n"); printf(" -C = Case sensitive search\n"); printf(" -N = Display only names of files containing search_string\n"); printf(" -Eexe_name = execute an editor or list utility using the file name\n"); printf(" of files containing the search_string."); exit(1); } if(sfilename[0] == '\0') { // if no search file specified, search all files. strcpy(sfilename,"*.*"); } if(pattern[0] == '\0') { // if a pattern wasn't specified, then ask for it. printf("\nASCII String Search Utility\n\n"); printf("Enter Search String: "); gets(pattern); if(pattern[0] == '\0') { exit(0); } } // build the list of files to search. status = build_list(sfilename); if(0 == status) { printf("No files found\n"); status = ALLDONE; } else if(status == -1) { printf("Not enough memory\n"); } else { scanfile = file_list; status = OK; } if(caseflg == FALSE) { // if user didn't specify case sensitive search, then make the // pattern lower case. strlwr(pattern); } patlen = strlen(pattern); p = &pattern[0]; while((status == OK) && ((pf = fopen(scanfile->name,"r")) != NULL)) { if(flistflg == FALSE) { printf("Searching file: %-20s",scanfile->name); } pnum = 1; match_cnt = 0; line_count = 0; scr_line_count = 0; while((fgetline(test_string,FILE_LINE_LENGTH,pf) != 0)) { s = &test_string[0]; // string pointer match_stat = FALSE; if(caseflg == FALSE) { // case insensitive search of the line. while((*s != '\0') && (match_stat == FALSE)) { // if the current character matches, then // check for the rest of the pattern (this eliminates // many calls to the string compare function). if((*p == tolower(*s)) && (0 == strnicmp(s,p,patlen))) { match_stat = TRUE; } else { s++; } } } else { // case sensitive search of the line. while((*s != '\0') && (match_stat == FALSE)) { if((*p == *s) && (0 == strncmp(s,p,patlen))) { match_stat = TRUE; } else { s++; } } } if(match_stat == TRUE) { // if a match is found: if(flistflg == FALSE) { match_cnt++; if(match_cnt == 1) { printf("\n\nLINE: MATCHING STRING\n\n"); } printf("%4d: %-1.70s\n",line_count,&test_string[0]); scr_line_count++; } else { match_cnt++; break; } } line_count++; if((scr_line_count >= 18) && (flistflg == FALSE)) { printf("\nPress a key to continue or to go to next file."); com = getch(); if(com == '\0') { getch(); } else if(com == '\033') { // if escape key pressed. break; } if(status == OK) { pnum++; scr_line_count = 0; printf("**********************************************\n"); printf(" File: %s Screen %d\n",scanfile->name,pnum); printf("Search string: %s\n\n",argv[1]); printf("LINE: MATCHING STRING\n\n"); } } } fclose(pf); if(flistflg == FALSE) { if(match_cnt != 0) { if(match_cnt == 1) { printf("\n%6d match in file %s",match_cnt,scanfile->name); } else { printf("\n%6d matches in file %s",match_cnt,scanfile->name); } printf("\n ... press key to continue, Esc to quit or \'L\' to List file.\n"); com = getch(); if(com == '\0') { getch(); } else if(com == '\033') { // if escape key pressed. status++; /* quit */ } else if((com == 'l') || (com == 'L')) { strcpy(listcom,execcom); strcat(listcom," "); strcat(listcom,scanfile->name); system(listcom); } } else { printf(" No matches\n"); } } else { if(match_cnt != 0) { printf("\n%s",scanfile->name); } } if(status == OK) { // Find the next file. if(scanfile->next != NULL) { scanfile = scanfile->next; } else { status = ALLDONE; } } } } // build file list. build_list(sfilename) char *sfilename; { char *pTmp; char szPath[80]; int sPos; int status; struct f_list *listfile; // file list structure. struct find_t ffStruct; // file search structure. strcpy(szPath,sfilename); // if path specified, extract it. sPos = strlen(szPath) - 1; pTmp = &szPath[0] + sPos; while((sPos > 0) && (*pTmp != '\\')) { pTmp--; sPos--; } if(sPos > 0) { // leave the backslash on the path. pTmp++; } *pTmp = '\0'; // find the first source file. status = _dos_findfirst(sfilename,_A_NORMAL,&ffStruct); if(status != 0) { return(0); } else { file_list = (struct f_list *)malloc(sizeof(struct f_list)); if(file_list == NULL) { return(-1); // out of memory. } listfile = file_list; strcpy(listfile->name,szPath); // get directory name. strcat(listfile->name,ffStruct.name); // append file name. while(status == 0) { status = _dos_findnext(&ffStruct); if(status == 0) { listfile->next = (struct f_list *)malloc(sizeof(struct f_list)); listfile = listfile->next; /* Source working file name */ strcpy(listfile->name,szPath); // get directory name. strcat(listfile->name,ffStruct.name); // append file name. } else { listfile->next = NULL; } } } return(1); } // Read a line or buffer from the file. fgetline(line,buflen,fp) char *line; unsigned buflen; FILE *fp; { int filstat; register int lchr; register char *pbuf; buflen--; // leave space for NULL. filstat = 1; pbuf = line; do { lchr = getc(fp); if(lchr == '\r') // skip carriage returns. { lchr = getc(fp); } if(lchr == EOF) // end of file. { filstat = 0; } else if(lchr == (int)'\n') { lchr = (int)'\0'; } *pbuf = (char)lchr; pbuf++; buflen--; } while((lchr != '\0') && (buflen > 0) && (filstat != 0)); *pbuf = '\0'; return(filstat); }