Advertisement
Guest User

Untitled

a guest
Apr 29th, 2013
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.24 KB | None | 0 0
  1. #include <dirent.h>
  2. #include <errno.h>
  3. #include <libgen.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <sys/wait.h>
  10. #include <unistd.h>
  11.  
  12. int badgrep(const char *file, int size, const char *pattern, int plen);
  13. int KMP_index(const char *data, int dlen, const char *pattern, int plen);
  14. void KMP_failure(const char *pattern, char *failure, int plen);
  15. void ffail(const char *file);
  16.  
  17. char *prog_invoked;
  18.  
  19. int main(int argc, char const *argv[])
  20. {
  21.     prog_invoked = basename((char *)argv[0]);
  22.     if (argc < 4) {
  23.         fprintf(stderr, "%s: %s\n", prog_invoked, "Too few arguments");
  24.         exit(EXIT_FAILURE);
  25.     }
  26.  
  27.     char *dirpath = NULL;
  28.     if ((dirpath = realpath(argv[1],dirpath)) == NULL) {
  29.         ffail(argv[1]);
  30.         exit(EXIT_FAILURE);
  31.     }
  32.  
  33.     DIR *dir = NULL;
  34.     if ((dir = opendir(dirpath)) == NULL) {
  35.         ffail(dirpath);
  36.         exit(EXIT_FAILURE);
  37.     }
  38.  
  39.     struct dirent *item;
  40.     int psize = strlen(argv[2]);
  41.    
  42.     int pid = 0;
  43.     int status = 0;
  44.     int max_active = atoi(argv[3]);
  45.     int now_active = 0;
  46.  
  47.     chdir(argv[1]);
  48.     int size = 0;
  49.     char *rpath = NULL;
  50.  
  51.     /*  Spawn children, limiting to max_active  */
  52.     for (; (item = readdir(dir)) != NULL; ++now_active) {
  53.         for (; now_active >= max_active; --now_active)
  54.             wait(&status);
  55.         if ((item->d_name[0] == '.') || (item->d_type == 'd')) {
  56.             --now_active;
  57.             continue;
  58.         }
  59.         pid = fork();
  60.         // Error
  61.         if (pid < 0) {
  62.             fprintf(stderr, "%s: %s\n", prog_invoked,strerror(errno));
  63.             exit(EXIT_FAILURE);
  64.         }
  65.         // Child
  66.         if (pid == 0) {
  67.             if ((rpath = realpath(item->d_name,rpath)) == NULL) {
  68.                 ffail(item->d_name);
  69.                 exit(EXIT_FAILURE);
  70.             }
  71.             struct stat *st = (struct stat *)malloc(sizeof(struct stat));
  72.             if (stat(rpath, st) == -1) {
  73.                 ffail(rpath);
  74.                 exit(EXIT_FAILURE);
  75.             }
  76.             size = (int)st->st_size;
  77.  
  78.             if (S_ISREG(st->st_mode))
  79.             {
  80.                 int has;
  81.                 if ((has = badgrep(rpath, size, argv[2], psize)) > 0) {
  82.                     printf("[%d] %s\t%d times in %d bytes\n", getpid(), rpath, has, size);
  83.                 }
  84.             }
  85.             free(st);
  86.             free(rpath);
  87.  
  88.             exit(EXIT_SUCCESS);
  89.         }
  90.     }
  91.     for (; now_active != 0; --now_active)
  92.             wait(&status);
  93.     closedir(dir);
  94.  
  95.     exit(EXIT_SUCCESS);
  96. }
  97.  
  98. void ffail(const char *file)
  99. {
  100.   fprintf(stderr, "%s: %s: %s\n", prog_invoked, file, strerror(errno));
  101. }
  102.  
  103. /*  The Knuth-Morris-Pratt algorithm  */
  104. int KMP_index(const char *data, int dlen, const char *pattern, int plen)
  105. {
  106.     static int start = 0;
  107.     char failure[plen];
  108.     KMP_failure(pattern, failure, plen);
  109.  
  110.     int j = 0, i = 0;
  111.  
  112.     for (i = start; i < dlen; i++) {
  113.         while ((j > 0) && pattern[j] != data[i]) {
  114.             j = failure[j-1];
  115.         }
  116.         if (pattern[j] == data[i]) {
  117.             j++;
  118.         }
  119.         if (j == plen) {
  120.             start = i + plen;
  121.             return i - plen + 1;
  122.         }
  123.     }
  124.     return -1;
  125. }
  126. void KMP_failure(const char *pattern, char *failure, int plen)
  127. {
  128.     int j = 0, i = 0;
  129.     for (i = 1; i < plen; i++) {
  130.         while ((j > 0) && pattern[j] != pattern[i]) {
  131.             j = failure[j - 1];
  132.         }
  133.         if (pattern[j] == pattern[i]) {
  134.             j++;
  135.         }
  136.         failure[i] = j;
  137.     }
  138. }
  139.  
  140.  
  141. /*  Quick n dirty search for pattern in file  */
  142. int badgrep(const char *file, int size, const char *pattern, int plen)
  143. {
  144.     char *array = (char *)malloc(size);
  145.  
  146.     FILE *stream;
  147.     if ((stream = fopen(file, "r")) == NULL) {
  148.         ffail(file);
  149.         return -1;
  150.     }
  151.     char c = 0;
  152.     int i = 0;
  153.     while ((c = fgetc(stream)) != EOF) {
  154.         array[i++] = c;
  155.     }
  156.     if (ferror(stream)) {
  157.         ffail(file);
  158.         return -1;
  159.     }
  160.     fclose(stream);
  161.  
  162.     int count = 0;
  163.     int pos = -1;
  164.     while ((pos = KMP_index(array, size, pattern, plen)) > -1) {
  165.         count++;
  166.     }
  167.     free(array);
  168.     return count;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement