Recursive String Search
Here is another one of those simple programs that are missing on the Windows platform; a functioning string search tool! The program's scheme is somewhat similar to using the UNIX grep command's combination of the '-n' '-i' and '-r' switches. It will search in a directory and it's sub-directories for a fixed case-insensitive string and display the name of each file, the line number and the line itself where that string is found.
Here's is a link to the binary for Win32 (compiled with MinGW) and here's the source code:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <limits.h> #include <unistd.h> #include <dirent.h> static char line[1024]; static void recurse(char *path, char *string, int len) { char full_path[PATH_MAX]; int n, match, name_shown, line_no; struct dirent *entry; struct stat st; DIR *dh; FILE *fh; dh = opendir(path); if (dh == NULL) { fprintf(stderr, "Warning: Unable to open directory: %s\n", path); return; } while ((entry = readdir(dh))) { if (entry->d_name[0] == '.') continue; /* Ignore files with leading dot. */ #ifdef WINNT snprintf(full_path, PATH_MAX, "%s\\%s", path, entry->d_name); #else snprintf(full_path, PATH_MAX, "%s/%s", path, entry->d_name); #endif stat(full_path, &st); if (S_ISDIR(st.st_mode)) { /* Traverse. */ recurse(full_path, string, len); } else if (S_ISREG(st.st_mode)) { /* Search. */ fh = fopen(full_path, "r"); if (fh == NULL) { fprintf(stderr, "Warning: Unable to open file: %s\n", full_path); continue; } name_shown = line_no = 0; while (fgets(line, 1024, fh) != NULL) { line_no++; match = 0; for (n = 0; line[n] != '\0'; n++) { if (toupper(line[n]) == toupper(string[match])) { match++; if (match >= len) { if (! name_shown) { printf("%s\n", full_path); name_shown = 1; } printf("%d:%s", line_no, line); break; } } else { match = 0; } } } fclose(fh); } } closedir(dh); return; } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, "Usage: %s <directory> <string>\n", argv[0]); return 1; } recurse(argv[1], argv[2], strlen(argv[2])); return 0; }