home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / forum5.lzh / SPRACHEN / C / FIND / find.c < prev    next >
C/C++ Source or Header  |  1988-04-13  |  9KB  |  314 lines

  1. /* find.c
  2.  *
  3.  * 'find' sucht rekursiv nach Files mit bestimmten Eigenschaften und
  4.  * fuehrt dann Operationen auf diese gefundenen Files aus
  5.  *
  6.  * Uwe Simon      April 1988
  7.  *
  8.  * Dieses Programm ist PD-Software !!!!!!
  9.  * Es basiert auf du.c von Tom Leitner, Graz
  10.  *
  11.  */
  12.  
  13.  
  14. /* system includes */
  15.  
  16. #include <stdio.h>
  17. #include <dir.h>
  18. #include <modes.h>
  19. #include <direct.h>
  20. #include <time.h>
  21.  
  22. /* constants & macros */
  23.  
  24. #define RBF (1)                 /* random block file found opened       */
  25. #define PIPE (2)                /* pipe file opened                     */
  26. #define NET (4)                 /* network file opened                  */
  27. #define TRUE 1                  /* logical true                         */
  28. #define FALSE 0                 /* logical false                        */
  29. #define KB(x) (x+1023L)/1024    /* formula to calculate kB from bytes   */
  30. #define SECT(x) (x+255L)/256    /* formula to calc. sectors from bytes  */
  31. #define MAXPATH 256             /* max. # of characters for path name   */
  32. #define EQ 0
  33. #define LESS 1
  34. #define MORE 2
  35.  
  36. /* global variables */
  37.  
  38. char path[MAXPATH] = "";        /* string to store the path             */
  39. char *root;                     /* root directory to start from         */
  40. int max_level=1000;             /* max level to go in filesystem */
  41. int print_flag=FALSE;
  42. char *f_name=NULL;              /* filename to look for */
  43. char *exec_str=NULL;            /* command to execute */
  44. int ask=0;                      /* ask for command flag */
  45. int user=0,group=0,perm=0,size=-1,t_f=1;
  46. int user_q=1,group_q=1,name_q=1,size_q=0,perm_q;
  47.  
  48. /*-------------------------------- M A I N ----------------------------------*/
  49.  
  50. main(argc, argv)
  51.         int argc;
  52.         char *argv[];
  53. {
  54.         get_parms(argc, argv);
  55.         findfile(0,root);
  56. }
  57.  
  58. /*-------------------- parses command line for parameters --------------------*/
  59.  
  60. get_parms(argc,argv)
  61. int argc;
  62. char *argv[];
  63. {
  64.         char *s;
  65.         int pc = 0;
  66.         while (--argc>0) {
  67.                 if ((*++argv)[0] == '-') {
  68.                     if(strlen(argv[0])>1) {
  69.                         if(argv[0][2]=='=') s=&argv[0][3];
  70.                         else s=&argv[0][2];
  71.                     } else s=NULL;
  72.                      switch(toupper(argv[0][1])) {
  73.                          case '~': 
  74.                          case '!': 
  75.                              t_f=FALSE;
  76.                              break;
  77.                          case 'O':
  78.                              print_flag = TRUE;
  79.                              break;
  80.                          case 'U':
  81.                              if(s[0]=='-') { user_q=0; s++;}
  82.                              user=atoi(s);
  83.                              break;
  84.                          case 'G':
  85.                              if(s[0]=='-') { group_q=0; s++;}
  86.                              group=atoi(s);
  87.                              break;
  88.                          case 'S':
  89.                             switch(s[0]) {
  90.                                 case '+': size_q=LESS; s++; break;
  91.                                 case '-': size_q=MORE; s++; break;
  92.                                 default: size_q=EQ;
  93.                             }        
  94.                             size=atoi(s);
  95.                             break;
  96.                          case 'P':
  97.                              perm=0;
  98.                              while(*s) {
  99.                                  perm= (perm<<3)+*s++-'0';
  100.                              }
  101.                              break;
  102.                          case 'A': ask=1;
  103.                          case 'E':
  104.                              exec_str=s;
  105.                              break;
  106.                          case 'N':
  107.                              if(s[0]=='-') { name_q=0; s++;}
  108.                              f_name=s;
  109.                              break;
  110.                          case 'L':
  111.                              max_level=atoi(s);
  112.                              break;
  113.                          case '?':
  114.                              usage();
  115.                              exit(0);
  116.                          default:
  117.                              _errmsg(0,"unknown option '%c'\n",argv[0][1]);
  118.                              exit(1);
  119.                      }
  120.                 }
  121.                 else if (pc == 0) {
  122.                         root = argv[0];
  123.                         pc++;
  124.                 } else exit(_errmsg(1,"only one parameter allowed"));
  125.         }
  126.         if (pc == 0) root = ".";
  127. }
  128.  
  129. /*------------------------- print usage explanations -------------------------*/
  130.  
  131. #define E(txt) fprintf(stderr, txt)
  132. usage()
  133. {
  134.         E("Syntax: find {<opts>} [<path>]\n");
  135.         E("Function: finds files in Filesystem\n");
  136.         E("Options :\n");
  137.         E("\t-o              output the found pathnames\n");
  138.         E("\t-~              only non matching files\n");
  139.         E("\t-n=[-]<string>  files with name <string> (wildcards allowed)\n");
  140.         E("\t-p=<num>        files with permissions <num> (<num> is octal)\n");
  141.         E("\t-u=[-]<num>     files which belong to user <num>\n");
  142.         E("\t-g=[-]<num>     files which belong to group <num>\n");
  143.         E("\t-s=[+|-]<num>   files are <num> blocks long (256 Byte/Block)\n");
  144.         E("\t-e=<string>     execute <string> on matching files\n");
  145.         E("\t-a=<string>     ask for executing <string> on matching files\n");
  146.         E("\t-l=<num>        recursive search to depth <num>\n");
  147. }
  148. #undef E(txt)
  149.  
  150. /*------------------------------ main algorithm ------------------------------*/
  151.  
  152. findfile(level, filename )
  153. char *filename;
  154. {
  155.   unsigned long size=0L;
  156.   int fd, pl, dfiles;
  157.   DIR *dirp;
  158.   struct direct *dirrec;
  159.   static struct fildes stat;
  160.  
  161.   
  162. /* setup the cumulative path name */
  163.         
  164.   if(level>=max_level) return;
  165.   
  166.   pl = strlen(path);
  167.   if (pl) strncat(path, "/", MAXPATH);
  168.   strncat(path, filename, MAXPATH);
  169.   
  170.  
  171. /* try to open the file */
  172.  
  173.   if( ((fd=open(filename,S_IREAD)) < 0) &&              /* regular file ? */
  174.       ((fd=open(filename,S_IFDIR|S_IREAD)) < 0) )       /* directory ?    */
  175.     fprintf(stderr,"Cannot open '%s'\n", filename);
  176.     
  177. /* successfully opened. check if it's on the right device */
  178.  
  179.   else {
  180.     if(_gs_gfd(fd, &stat,sizeof(struct fildes))!=-1) {
  181.  
  182. /* now test if it is the file we want */
  183.  
  184.        test_file(filename,stat,fd);
  185.                   
  186. /* ok. we're on a valid device : now check if we hit a directory file */
  187.  
  188.        if( stat.fd_att & S_IFDIR ) {
  189.                
  190. /* yes. we hit a directory file. close the FD and CHD into it. */
  191.  
  192.           close(fd);
  193.           if(level==max_level-1) {
  194.                 path[pl] = (char) NULL;
  195.               return;
  196.           }
  197.           if( (dirp = opendir( filename )) && !chdir( filename) ) {
  198.                   
  199. /* skip the "." and the ".." entries */
  200.  
  201.             readdir(dirp); readdir( dirp );
  202.             
  203. /* get file sizes of all files in this directory */
  204.  
  205.             while (dirrec = readdir (dirp))
  206.               if (dirrec->d_addr) {
  207.                  findfile(level+1,dirrec->d_name);
  208.               }
  209.                  
  210. /* end of directory : close it and print the results */
  211.  
  212.             closedir( dirp );
  213.             chdir("..");
  214.           }
  215.           
  216. /* ERROR occurred : can't CHD into this directory. */
  217.  
  218.           else
  219.             fprintf(stderr, "Cannot chdir '%s'\n", filename);
  220.  
  221. /* the given filename was no directory. it's a normal file so just get its
  222.    size and increment the file count */
  223.    
  224.        } else close( fd );
  225.      }
  226.      
  227. /* the given file name is not on a valid device */
  228.  
  229.      else
  230.      fprintf(stderr,"Cannot read file - not a block special device\n");
  231.   }
  232.   
  233. /* reset the cumulative PATH string */
  234.  
  235.   path[pl] = (char) NULL;
  236.   return( size );
  237. }
  238.  
  239. /*-------------------------- print one table entry ---------------------------*/
  240.  
  241. test_file(name,pfd,f)
  242. char *name;
  243. struct fildes pfd;
  244. int f;
  245. {
  246.     int match,h_size;
  247.     match=1;
  248.     if(f_name) match=match&& ((_cmpnam(name,f_name,strlen(f_name))==0)==name_q);
  249.     if(user) match=match&& ((user==pfd.fd_own[1])==user_q);
  250.     if(group) match=match&& ((group==pfd.fd_own[0])==group_q);
  251.     if(perm) match=match&&((perm&pfd.fd_att)==perm);
  252.     if(size>=0) {
  253.         h_size=(_gs_size(f)+255)/256;
  254.         switch(size_q) {
  255.             case EQ:   match=match&&(size==h_size); break;
  256.             case MORE: match=match&&(size>=h_size); break;
  257.             case LESS: match=match&&(size<=h_size); break;
  258.         }
  259.     }
  260.     if(match==t_f) do_command(name);
  261. }
  262.  
  263.  
  264. char *replace(str,s1,s2)
  265. char *str,*s1,*s2;   /* relace first place from s1 in str with s2 */
  266. {
  267.     char sh[256],*pa;
  268.     int pos;
  269.     if((pos=findstr(1,str,s1))==NULL) return(NULL);
  270.     else {
  271.         pa=&str[pos-1+strlen(s1)];
  272.         strncpy(sh,str,pos-1);
  273.         sh[pos-1]='\0';
  274.         strcat(sh,s2);
  275.         strcat(sh,pa);
  276.     }
  277.     strcpy(str,sh);  /* copy back new string */
  278.     return(&str[pos-1]);
  279. }
  280.  
  281.  
  282. do_command(name)
  283. char *name;
  284. {
  285.     char str[256],h[5],*pa;
  286.     int pos,ok;
  287.     
  288.     ok=0;
  289.     if(print_flag) printf("%s\n",path);
  290.     if(exec_str) {
  291.         strcpy(str,exec_str);
  292.         for(;replace(str,"{}",name););  /* replace all {} with filename */
  293.         if(ask) {
  294.             fprintf(stderr,"Pathname: %s\n",path);
  295.             fprintf(stderr,"execute: %s\n",str);
  296.             do {
  297.                 fgets(h,4,stdin);
  298.                 switch(toupper(h[0])) {
  299.                     case 'Y': ok=1; break;
  300.                     case 'N': return; break;
  301.                     case 'C': exit(0);
  302.                     default: printf("\nY(es, N(o or C(ancel\n");
  303.                 }
  304.             } while(!ok);
  305.             
  306.         }
  307.         system(str);
  308.     }
  309. }
  310.  
  311.  
  312. /* E O F */
  313.  
  314.