home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 3 / FREEWARE.BIN / ms_dos / sfind105 / sfind.c < prev    next >
Text File  |  1980-01-02  |  8KB  |  403 lines

  1. /**
  2.     SFIND : Same File Find Utility
  3.  
  4.     Ver 1.00  90/10/03  Creation
  5.     Ver 1.01  90/10/24  Bug at -e Process
  6.     Ver 1.02  90/10/26  Bug at Previous Stack & Drive Check
  7.     Ver 1.03  90/11/13  Module Size Compaction
  8.     Ver 1.04  90/12/29  Bug at Perfect Match File
  9.     Ver 1.05  91/01/02  -T Support
  10. **/
  11. #define    TITLE    "Same File Find Utility  Ver 1.05 (c)masuo 1990,1991.\n\n"
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <dos.h>
  17. #if !LATTICE
  18. #include <conio.h>
  19. #include <dir.h>
  20. #endif
  21. typedef    unsigned int    uint;
  22. extern int    toupper(int);
  23. #define    isdigit(c)    ('0'<=c && c<='9')
  24. #define EOS    '\0'
  25. #define ESC    '\x1b'
  26. #define CR    '\r'
  27. #define ERROR    (-1)
  28. #if LATTICE
  29. #define    FALSE    0
  30. #define    TRUE    1
  31. #define    OFF    0
  32. #define    ON    1
  33. #define    NO    0
  34. #define    YES    1
  35. #define FA_RDONLY    0x01        /* Read only attribute */
  36. #define FA_HIDDEN    0x02        /* Hidden file */
  37. #define FA_SYSTEM    0x04        /* System file */
  38. #define FA_DIREC    0x10        /* Directory */
  39. #define    ff_attrib    attr
  40. #define    ff_name        name
  41. #define    setdta(a)    chgdta(a)
  42. #define    findfirst(a,b,c)    dfind(b,a,c)
  43. #define    findnext(a)    dnext(a)
  44. #define    getdisk()    getdsk()
  45. #define    setdisk(d)    chgdsk(d)
  46. #else
  47. typedef    unsigned char    byte;
  48. typedef    enum {FALSE, TRUE}    boolean;
  49. typedef    enum {OFF, ON}        sw;
  50. typedef    enum {NO, YES}        FLAG;
  51. #endif
  52.  
  53. struct FBUF {
  54.     struct    FBUF *after;
  55.     char    *dirptr;
  56.     long    size;
  57.     union {
  58.         struct {
  59.             uint    time;
  60.             uint    date;
  61.         } t;
  62.         long ltime;
  63.     }d;
  64.     char    attr;
  65.     char    name[13];
  66. };
  67.  
  68. struct    FBUF *fbftop=NULL;
  69. struct    FBUF *filebuf;
  70. byte    filechk=OFF;
  71. byte    permatch=OFF;
  72. byte    timesame=OFF;
  73.  
  74. void dispfile(int, struct FBUF *);
  75. int  u_strcmp(char *, char *);
  76. void u_strcat(char *, char *);
  77. int  buf_scan(struct FBUF *);
  78. void get_dir(char *);
  79. int  select(void);
  80. int  yesno(void);
  81.  
  82. void dispfile(num, files)
  83. int num;
  84. struct FBUF *files;
  85. {
  86.     int year, mon, day, hour, min, sec;
  87.  
  88.     sec =(files->d.t.time&0x001f)*2;
  89.     min =(files->d.t.time&0x7ff)/0x20;
  90.     hour= files->d.t.time/0x0800;
  91.     day = files->d.t.date&0x001f;
  92.     mon =(files->d.t.date&0x01ff)/0x20;
  93.     year= files->d.t.date/0x200+1980;
  94.     fprintf(stdout,"\x1b[33m%2d\x1b[37m %-14s%8ld  %04d-%02d-%02d %02d:%02d:%02d  %s\x1b[m\n",
  95.         num, files->name, files->size, year, mon, day, hour, min, sec,
  96.         files->dirptr);
  97. }
  98.  
  99. u_strcmp(p, q)
  100. char *p, *q;
  101. {
  102.     while(1){
  103.         if((!*p && !*q) || (filechk && *p=='.' && *q=='.'))
  104.             break;
  105.         if(*p!=*q)
  106.             return TRUE;
  107.         p++, q++;
  108.     }
  109.     return FALSE;
  110. }
  111.  
  112. void u_strcat(d, s)
  113. char *d, *s;
  114. {
  115.     char *t=d;
  116.  
  117.     while(*t)
  118.         t++;
  119.     while(*s){
  120.         if(!strrchr(d,*s)){
  121.             *t++=*s;
  122.             *t=EOS;
  123.         }
  124.         s++;
  125.     }
  126. }
  127.  
  128. int buf_scan(buf)
  129. struct FBUF *buf;
  130. {
  131.     int cnt=0;
  132.     struct FBUF *a;
  133.  
  134.     for(a=buf->after; a; a=a->after){
  135.         if(!timesame)
  136.             if(u_strcmp(a->name, buf->name))
  137.                 break;
  138.         if(timesame || permatch)
  139.             if(a->d.ltime!=buf->d.ltime||a->size!=buf->size)
  140.                 break;
  141.         cnt++;
  142.     }
  143.     return cnt;
  144. }
  145.  
  146. void get_dir(path)
  147. char *path;
  148. {
  149. #if LATTICE
  150.     struct FILEINFO info;
  151. #else
  152.     struct ffblk info;
  153. #endif
  154.     char *dirbuf;
  155.     char *lastp=path+strlen(path);
  156. #if !LATTICE
  157.     long *tt;
  158. #endif
  159.     int chk;
  160.     struct FBUF *tmp, *prev;
  161.  
  162.     if(*(lastp-1)!='\\')
  163.         strcpy(lastp++,"\\");
  164.     dirbuf=malloc(strlen(path)+1);
  165.     if(!dirbuf){
  166.         fprintf(stderr, "malloc error(dirbuf)\n");
  167.         exit(2);
  168.     }
  169.     strcpy(dirbuf, path);
  170.     strcpy(lastp,"*.*");
  171.     setdta((char *)&info);
  172.     if(!findfirst(path, &info, 0x37)){
  173.         do{
  174.             if(info.ff_attrib & FA_DIREC){
  175.                 if(info.ff_name[0]!='.'){
  176.                     strcpy(lastp, info.ff_name);
  177.                     get_dir(path);
  178.                     setdta((char *)&info);
  179.                 }
  180.             }else if(!(info.ff_attrib & (FA_SYSTEM|FA_HIDDEN|FA_RDONLY))){
  181.                 filebuf=(struct FBUF *)malloc(sizeof(*filebuf));
  182.                 if(!filebuf){
  183.                     fprintf(stderr, "malloc error(filebuf)\n");
  184.                     exit(2);
  185.                 }
  186.                 for(tmp=fbftop; tmp; prev=tmp, tmp=tmp->after){
  187.                     if(!timesame){
  188.                         chk=strcmp(info.ff_name, tmp->name);
  189.                         if(chk<0)
  190.                             break;
  191.                     }
  192.                     if(timesame||(permatch && !chk)){
  193. #if LATTICE
  194.                         if(info.time<tmp->d.ltime)
  195.                             break;
  196.                         else if(info.time==tmp->d.ltime && info.size<tmp->size)
  197.                             break;
  198. #else
  199.                         tt=(long *)&info.ff_ftime;
  200.                         if(*tt<tmp->d.ltime)
  201.                             break;
  202.                         else if(*tt==tmp->d.ltime && info.ff_fsize<tmp->size)
  203.                             break;
  204. #endif
  205.                     }
  206.                 }
  207.                 filebuf->after=tmp;
  208.                 if(tmp==fbftop)
  209.                     fbftop=filebuf;
  210.                 else
  211.                     prev->after=filebuf;
  212.                 filebuf->dirptr=dirbuf;
  213.                 filebuf->attr=info.ff_attrib;
  214. #if LATTICE
  215.                 filebuf->d.ltime=info.time;
  216.                 filebuf->size=info.size;
  217. #else
  218.                 filebuf->d.t.time=info.ff_ftime;
  219.                 filebuf->d.t.date=info.ff_fdate;
  220.                 filebuf->size=info.ff_fsize;
  221. #endif
  222.                 strcpy(filebuf->name, info.ff_name);
  223.             }
  224.         }while(!findnext(&info));
  225.     }
  226. }
  227.  
  228. int select(void)
  229. {
  230.     int ch;
  231.  
  232.     while(1){
  233.         ch=getch();
  234.         if(ch=='D' || ch=='d' || ch==CR || ch==ESC)
  235.             break;
  236.     }
  237.     return ch;
  238. }
  239.  
  240. int yesno(void)
  241. {
  242.     while(1){
  243.         switch(toupper(getch())){
  244.         case 'Y':
  245.             return YES;
  246.         case 'N':
  247.         case ESC:
  248.             return NO;
  249.         }
  250.     }
  251. }
  252.  
  253. void main(argc, argv)
  254. int argc;
  255. char *argv[];
  256. {
  257.     struct FBUF *filebuf, *tmp;
  258.     int i, j, cnt, ch;
  259.     int curdrv=getdisk();
  260.     char drvs[128], work[128];
  261.     static char *usage[]={
  262.         "usage:    ",""," [opt] drives...\n",
  263.         "option:    -e=Extent Nocheck\n",
  264.         "    -p=Perfect Same\n",
  265.         "    -t=Time & Date & Size Same\n",
  266.         "    -?=This Message\n",
  267.         NULL
  268.     };
  269.  
  270.     fprintf(stderr,TITLE);
  271.     usage[1]=strrchr(*argv,'\\')+1;
  272.     drvs[0]=EOS;
  273.     if(--argc){
  274.         while(argc--){
  275.             if(**++argv=='-' || **argv=='/'){
  276.                 switch(toupper(*(*argv+1))){
  277.                 case 'E':
  278.                     filechk=ON;
  279.                     break;
  280.                 case 'P':
  281.                     permatch=ON;
  282.                     break;
  283.                 case 'T':
  284.                     timesame=ON;
  285.                     break;
  286.                 default:
  287.                     {
  288.                         char **usg;
  289.  
  290.                         *strrchr(usage[1],'.')=EOS;
  291.                         for(usg=usage; *usg; usg++)
  292.                             fprintf(stderr,*usg);
  293.                     }
  294.                     exit(1);
  295.                 }
  296.             }else{
  297.                 u_strcat(drvs, *argv);
  298.             }
  299.         }
  300.     }
  301.     if(permatch)
  302.         timesame=OFF;
  303.     if(!drvs[0]){
  304.         drvs[0]=curdrv+'A';
  305.         drvs[1]=EOS;
  306.     }
  307.     for(i=0; drvs[i]; i++){
  308.         ch=toupper(drvs[i]);
  309.         setdisk(ch-'A');
  310.         if(getdisk()!=ch-'A'){
  311.             fprintf(stderr, "Invalid Drive specification: %c:\n",ch);
  312.         }else{
  313.             setdisk(curdrv);
  314.             work[0]=ch;
  315.             work[1]=':';
  316.             work[2]='\\';
  317.             work[3]=EOS;
  318.             get_dir(work);
  319.         }
  320.     }
  321.     for(filebuf=fbftop; filebuf; filebuf=filebuf->after){
  322. scan:    cnt=buf_scan(filebuf);
  323.         if(cnt){
  324.             for(i=0, tmp=filebuf; i<=cnt; i++,tmp=tmp->after)
  325.                 dispfile(i+1, tmp);
  326.             fprintf(stderr,"[1..%d/ESC/CR]",++cnt);
  327. retry:        ch=getch();
  328. #if !LATTICE
  329.             if(ch==0x03){
  330.                 fprintf(stderr,"^C\n");
  331.                 break;
  332.             }
  333. #endif
  334.             if(isdigit(ch)){
  335.                 i=ch-'0';
  336.                 fprintf(stderr,"%c",ch);
  337.                 if(i && i<=cnt/10 && cnt>9){
  338.                     ch=getch();
  339.                     if(ch!=CR){
  340.                         if(!isdigit(ch)){
  341.                             ch=ESC; goto errexit;
  342.                         }
  343.                         i=i*10+(ch-'0');
  344.                     }
  345.                 }
  346.                 if((!i) || (i>cnt)){
  347.                     ch=ESC;
  348.                 }else{
  349.                     for(j=1, tmp=filebuf; j<i; j++)
  350.                         tmp=tmp->after;
  351.                     strcpy(work, tmp->dirptr);
  352.                     strcat(work, tmp->name);
  353.                     fprintf(stderr, "\x1b[80D\x1b[7;31m%s\x1b[m ==> What Process [Del/CR/ESC]",work);
  354.                     switch(toupper(ch=select())){
  355.                     case CR:
  356.                         if(strlen(tmp->dirptr)>3)
  357.                             tmp->dirptr[strlen(tmp->dirptr)-1]=EOS;
  358.                         setdisk(tmp->dirptr[0]-'A');
  359.                         chdir(tmp->dirptr);
  360.                         fprintf(stderr, "\x1b[80D\x1b[K\n\x1b[7m%s\x1b[m",
  361.                             tmp->dirptr);
  362.                         exit(0);
  363.                     case 'D':
  364.                         fprintf(stderr, "\x1b[25DDelete OK (Y/N)\x1b[K");
  365.                         if(yesno()){
  366.                             unlink(work);
  367.                             fprintf(stderr, "\x1b[9Dd.\x1b[K\n");
  368.                             if(cnt>2){
  369.                                 if(i==1){
  370.                                     filebuf=filebuf->after;
  371.                                 }else{
  372.                                     for(j=2, tmp=filebuf; j<i; j++)
  373.                                         tmp=tmp->after;
  374.                                     tmp->after=tmp->after->after;
  375.                                 }
  376.                                 goto scan;
  377.                             }
  378.                         }
  379.                         break;
  380.                     }
  381.                     ch=CR;
  382.                 }
  383.             }
  384.             if(ch!=CR && ch!=ESC)
  385.                 goto retry;
  386. errexit:    fprintf(stderr,"\x1b[80D\x1b[K\n");
  387.             if(ch==ESC)
  388.                 break;
  389.             while(filebuf->after){
  390.                 if(!timesame)
  391.                     if(u_strcmp(filebuf->name, filebuf->after->name))
  392.                         break;
  393.                 if(timesame || permatch)
  394.                     if(filebuf->d.ltime!=filebuf->after->d.ltime
  395.                        ||filebuf->size   !=filebuf->after->size)
  396.                             break;
  397.                 filebuf=filebuf->after;
  398.             }
  399.         }
  400.     }
  401.     exit(0);
  402. }
  403.