/* | Text Search Utility by Jonathan Harm | | version 0.3.0(beta) | | This program is freeware | You can find updates and other source | code at http://change.to/opensource | | If you have any questions, comments, or | suggestions, send them to 110983@lycos.com | */ //TODO: //add more features /* | If you are using Linux, be sure to define | LINUX so the code will compile correctly */ #define WIN #include #include #include #include #include #include #ifdef WIN #include #include #endif #ifdef LINUX #include #endif main() { FILE *fn; DIR *dir; struct dirent *ent; char dirname[100], search[30], *ptr_success, buffer[31], *dirp, ch, dirname_ini[100]; int i, j, end_buffer, status, search_option, times_found = 0, results_page = 0, dirname_yes = 0; unsigned int length; dirp = dirname; #ifdef WIN system("CLS"); #endif printf("Text Serach Utility beta 3\nBy Jonathan Harm(110983@lycos.com)\n"); #ifdef WIN if( (fn = fopen("c:\\windows\\txtsrch.ini", "r")) == NULL) { dirname_yes = 0; //if there is no config file, then //set this to 0 } else if( (fn = fopen("c:\\windows\\txtsrch.ini", "r")) != NULL) { dirname_yes = 1; //if it got to here, then the config file //does exist, so set to 1 // get dirname from ini file fscanf(fn, "%s", &dirname_ini[0]); fclose(fn); } #endif /* stuff to add in the next version make the user enter a dir name and show them that when they run the program(i.e. Enter the directory to search default is c:\windows and they can specify a different one, but if they do, then update the ini file. Do the same thing for case sensitve search and remember to add code to search words only(dont forget BOOLEAN AND, OR for word search. | ie give this world <-- AND would have to find all the words in order for it to be succesful OR could be any word */ printf("\nEnter the directory to search\n"); if(dirname_yes == 1) printf("Default is [%s]\n", dirname_ini); gets(dirname); if(dirname[0] == NULL) //if user pressed enter for default { length = strlen(dirname_ini); for(i = 0; i < length; i++){ dirname[i] = dirname_ini[i]; //store dirname from ini to the dirname variable } } printf("\nEnter string to search\n"); gets(search); printf("\nCase insensitive?\n(Y/n)"); search_option = getc(stdin); search_option = toupper(search_option); //change to uppercase switch( search_option ) { //switch is to store 1 or 0 //to the search_option variable case 'Y': search_option = 1; break; case 'N': search_option = 0; break; default: search_option = 1; break; } #ifdef WIN //show user settings they have chosen printf("\nDo you want to save these settings?\n"); printf("Directory to search = [%s]\n", dirname); printf("(Y/n)"); //get y or n from user i = getc(stdin); i = toupper(i); //change to uppercase switch ( i ) { case 'Y': i = 1; break; case 'N': i = 0; break; default: i = 1; break; } if(i == 1) { if( (fn = fopen("c:\\windows\\txtsrch.ini", "w")) == NULL) { //if it can't create the ini file, then quit fprintf(stderr, "Cannot Create txtsrch.ini\n"); exit(1); } //save the settings to the file fprintf(fn, "%s\n", dirname); fclose(fn); } #endif /* Now look at the path to search in and change to that drive */ /* Also, do not assume that a windows user will be on the C drive */ /* in this next part, i is the drive letter */ #ifdef WIN i = dirname[0]; i -= 64; /* changes ascii value to number of letter in alphabet */ length = strlen(dirname); for(i = 0, j = 2; j < length; i++, j++) //j is 2 to allow for the :\ after the drive letter { dirname[i] = dirname[j]; } dirname[ length -= 2] = NULL; /* make sure that the path is terminated */ _chdrive(i); printf("%d", i); printf("\n%s", dirname); #endif dir = opendir( dirp ); //opens the directory while ((ent = readdir(dir)) != NULL) { if ( strcmp(ent->d_name,"..") != 0 && strcmp(ent->d_name,".") != 0 ) //thanks to Stee(http://www.stevec.plus.com/) for the line of code above { chdir(dirname); //change to the directory if ( (fn = fopen( ent->d_name , "r")) == NULL) { fprintf(stderr, "Error opening file %s\\%s", dirname, ent->d_name); exit(1); } for(i = 0; i < 30; i++) //first fill up the buffer. { status = fscanf(fn, "%c", &ch); buffer[i] = ch; //if the EOF is found before 30 characters if(status == EOF) //then break the loop { break; } } buffer[i] = '\0'; //put the null character in the end of the buffer end_buffer = i; //sets the end_buffer to '\0' or EOF, which ever //occurs first //this changes everything to lowercase to do //case insensitive searches if(search_option == 1) { for(i = 0; i < end_buffer; i++) { buffer[i] = tolower(buffer[i]); } for(i = 0; i < 30; i++) { search[i] = tolower(search[i]); if(search[i] == NULL) { break; } } if(i == 30) //this will truncate the search at { //30 characters if it is too long search[i] = '\0'; } } ptr_success = strstr(buffer, search); while(ptr_success == NULL) { if(ptr_success == NULL && end_buffer < 30) //dont go through the process { //of incrementing the buffer break; //if it isnt big enough } //end_buffer should always be either //NULL while(buffer[end_buffer] == NULL) { //if status == EOF, then NULL(which is what end_buffer //should be) is one less than status if(status == EOF) { --end_buffer; } if(end_buffer == 0) //don't let the program get stuck in the while loop { break; } ptr_success = strstr(buffer, search); //search if(ptr_success != NULL) //if the search was successful { //then it doesnt need to increment the buffer break; } for(i = 0, j = 1; j < end_buffer; i++, j++) { buffer[i] = buffer[j]; //move characters in buffer down one //to make room to increment to the next } status = buffer[--j] = fgetc(fn); //this line puts the next char in the buffer //and gets the status to check for EOF buffer[++j] = '\0'; //make sure end of buffer is NULL if(search_option == 1) { for(i = 0; i < end_buffer; i++) { buffer[i] = tolower(buffer[i]); } } } //end of "while(status == EOF || buffer[end_buffer] == NULL)" } // <-end of "while(ptr_success == NULL)" if (ptr_success != NULL) //if strstr returns NULL, then there was //no match found. { #ifdef WIN printf("Found match for your search in %s\\%s\n", dirname, ent->d_name); #endif #ifdef LINUX printf("Found match for your search in %s/%s\n", dirname, end->d_name); #endif ++times_found; //add one when it found a match ++results_page; //this is for determining when to go 2 next page if(results_page > 20) { printf("\n\npress ENTER to continue\n"); results_page = 0; gets(""); } } ptr_success = NULL; //need to set to NULL or it will //think the search was successful when it isn't fclose(fn); } //end of "while ((ent = readdir(dir)) != NULL)" } //end of if ( strcmp(ent->d_name,"..") != 0 && strcmp(ent->d_name,".") != 0 ) closedir(dir); printf("\nFound your search in %d files\n\n", times_found); printf("\n\nThank you for using The Text Search Utility.\n"); printf("You can find the latest updates at http://change.to/opensource"); return 0; }