home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 326.lha / ARPTools / src / Sf.c < prev    next >
C/C++ Source or Header  |  1989-12-27  |  7KB  |  336 lines

  1. /*
  2.           Sf - Search files in volumes or directories.
  3.  
  4.           Strictly based on the SF program by Andrea Suatoni published
  5.           in MC-Microcomputer 86, June 1989. Little enhancements by
  6.           Fabio Rossetti: resident support, NOCOL option.
  7.  
  8.           (c) 1989 by Fabio Rossetti
  9.  
  10.           To compile under Lattice C v5.0x use:
  11.  
  12.         lc -O -v -cus sf
  13.         blink lib:cres.o sf.o to sf lib lib:a.lib lib:lc.lib lib:amiga.lib sc sd nd
  14.  
  15. */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/lists.h>
  19. #include <exec/memory.h>
  20. #include <arpfunctions.h>
  21. #include <string.h>
  22. #include <libraries/arpbase.h>
  23. #include <libraries/dosextens.h>
  24.  
  25. #include <proto/dos.h>
  26. #include <proto/exec.h>
  27.  
  28. #define NO_ERROR 0
  29. #define ERROR_NO_MEM -101
  30.  
  31. typedef
  32.     struct
  33.     {
  34.     struct MinNode    dir_Node;
  35.     LONG        PathLen;
  36.     STRPTR        PathName;
  37.     }
  38.     DIR_ENTRY;
  39.  
  40. GLOBAL VOID (*_ONBREAK)();
  41.  
  42. UBYTE DateFormat = FORMAT_DOS;
  43. struct Process *Pr;
  44. struct ArpBase *ArpBase;
  45.  
  46. struct MinList DirList;
  47.  
  48. VOID Cleanup(r1,r2,msg)
  49. LONG r1,r2;
  50. STRPTR msg;
  51. {
  52.     if (msg) Puts(msg);
  53.     if (ArpBase) CloseLibrary((struct Library *)ArpBase);
  54.     Pr->pr_Result2 = r2;
  55.     exit(r1);
  56. }
  57.  
  58.  
  59. STRPTR StrUpper(Str)
  60. REGISTER STRPTR Str;
  61. {
  62.     REGISTER STRPTR r = Str;
  63.  
  64.     do
  65.     {
  66.     *Str = Toupper(*Str);
  67.     }
  68.  
  69.     while (*(++Str));
  70.     return(r);
  71. }
  72.  
  73. LONG AddDirEntry(PathNode,Dir)
  74. REGISTER STRPTR    PathNode,
  75.         Dir;
  76. {
  77.     REGISTER DIR_ENTRY *Entry;
  78.  
  79.     if ((Entry =
  80.         (DIR_ENTRY*) AllocMem(sizeof(DIR_ENTRY), MEMF_CLEAR)) == NULL)
  81.         return(ERROR_NO_MEM);
  82.     Entry->PathLen = strlen(PathNode) + strlen(Dir) + 2;
  83.     if((Entry->PathName =
  84.         (STRPTR) AllocMem(Entry->PathLen, MEMF_CLEAR)) == NULL)
  85.     {
  86.     FreeMem(Entry, sizeof(DIR_ENTRY));
  87.     return(ERROR_NO_MEM);
  88.     }
  89.  
  90.     strcpy(Entry->PathName, PathNode);
  91.  
  92.     TackOn(Entry->PathName, Dir);
  93.  
  94.     AddTail((struct List *) &DirList, (struct Node *) Entry);
  95.     return(0);
  96. }
  97.  
  98. VOID RemDirEntry()
  99. {
  100.  
  101.     REGISTER DIR_ENTRY *Entry;
  102.  
  103.     Entry = (DIR_ENTRY *) RemHead((struct List *) &DirList);
  104.  
  105.     FreeMem(Entry->PathName, Entry->PathLen);
  106.     FreeMem((STRPTR) Entry, sizeof(DIR_ENTRY));
  107. }
  108.  
  109. VOID FreeDirList()
  110. {
  111.     while (DirList.mlh_Head->mln_Succ)
  112.         RemDirEntry();
  113. }
  114.  
  115. VOID FindFile(ArgV)
  116.  
  117. STRPTR ArgV[];
  118.  
  119. #define    PATTERN    ArgV[0]
  120. #define    FILES    ArgV[1]
  121. #define    DIRS    ArgV[2]
  122. #define    QUICK    ArgV[3]
  123. #define    NOROOT    ArgV[4]
  124. #define NOCOL    ArgV[5]
  125.  
  126. {
  127.  
  128.     REGISTER struct FileLock    *DirLock;
  129.     REGISTER struct FileInfoBlock    *FileInfo;
  130.     REGISTER STRPTR            CurrentPath;
  131.     REGISTER LONG            Error;
  132.     REGISTER BOOL            Found = FALSE,
  133.                     First,
  134.                     Dir;
  135.         TEXT            Day    [12],
  136.                     Time    [10],
  137.                     Date    [10],
  138.                     StrToken[120],
  139.                     Path    [120];
  140.         WORD            Tabs = 0;
  141.         struct DateTime        DateTime;
  142.  
  143.     if ((FileInfo = (struct FileInfoBlock *)
  144.         AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
  145.     {
  146.     DateTime.dat_Format = DateFormat;
  147.     DateTime.dat_Flags = DTF_FUTURE;
  148.     DateTime.dat_StrDay = Day;
  149.     DateTime.dat_StrDate = Date;
  150.     DateTime.dat_StrTime = Time;
  151.     NewList((struct List *) &DirList);
  152.     *Path = '\0';
  153.  
  154.     if (NOROOT == NULL)
  155.         if (strchr(PATTERN, ':') == NULL)
  156.             strcpy(Path, ":");
  157.     strcat(Path, PATTERN);
  158.     PreParse((CurrentPath = StrUpper(BaseName(Path))), StrToken);
  159.     *CurrentPath = '\0';
  160.     if ((DirLock = (struct FileLock *) Lock(Path, ACCESS_READ)) == NULL)
  161.         Error = ERROR_INVALID_LOCK;
  162.         else
  163.         {
  164.         PathName((BPTR) DirLock, Path, 10);
  165.         UnLock((BPTR) DirLock);
  166.         Error  = AddDirEntry(Path,"");
  167.         }
  168.     while (DirList.mlh_Head->mln_Succ)
  169.         {
  170.         CurrentPath = ((DIR_ENTRY *) DirList.mlh_Head)->PathName;
  171.         if ((DirLock = (struct FileLock *) Lock(CurrentPath, ACCESS_READ)) ==
  172.                 (struct FileLock *) 0)
  173.         {
  174.         Error = ERROR_INVALID_LOCK;
  175.         break;
  176.         }
  177.         First = TRUE;
  178.         if (Examine((BPTR) DirLock, FileInfo))
  179.             {
  180.             while (ExNext((BPTR) DirLock, FileInfo))
  181.                 {
  182.                 if (Dir = (FileInfo->fib_DirEntryType >= 0))
  183.                     if ((Error = AddDirEntry(CurrentPath,
  184.                         FileInfo->fib_FileName)) != NO_ERROR)
  185.                     break;
  186.                 if (PatternMatch(StrToken,
  187.                     StrUpper(strcpy(Path, FileInfo->fib_FileName))) == TRUE)
  188.                     if (!(DIRS || FILES) ||
  189.                         (DIRS && Dir) ||
  190.                         (FILES && !Dir))
  191.                     {
  192.                     Found = TRUE;
  193.                     if (First)
  194.                     {
  195.                         if(Tabs)
  196.                         {
  197.                         Puts("");
  198.                         Tabs = 0;
  199.                         }
  200.                     if(NOCOL) Printf("\n\"%s\"\n",CurrentPath);
  201.                     else Printf("\n\033[33m\"%s\"\033[31m\n",
  202.                         CurrentPath);
  203.                     First = FALSE;
  204.                     }
  205.                 if (QUICK)
  206.                     {
  207.                     if (Dir)
  208.                         if (NOCOL) Printf("%s%-18s",(Tabs) ? "": "   ",
  209.                         FileInfo->fib_FileName);
  210.                         else Printf("\033[33m%s%-18s\033[31m",(Tabs) ? "": "   ",
  211.                         FileInfo->fib_FileName);
  212.                     else
  213.                     Printf("%s%-18s",(Tabs) ? "": "   ",
  214.                     FileInfo->fib_FileName);
  215.                     if (++Tabs == 4)
  216.                         {
  217.                         Tabs = 0;
  218.                         Puts("");
  219.                         }
  220.                     }
  221.                 else
  222.                 {
  223.                 DateTime.dat_Stamp.ds_Days = FileInfo->fib_Date.ds_Days;
  224.                 DateTime.dat_Stamp.ds_Minute= FileInfo->fib_Date.ds_Minute;
  225.                 DateTime.dat_Stamp.ds_Tick = FileInfo->fib_Date.ds_Tick;
  226.                 StamptoStr(&DateTime);
  227.                 Printf("    %-30s ", FileInfo->fib_FileName);
  228.                 if (Dir)
  229.                     Printf("  (dir)");
  230.                 else
  231.                     Printf("%7ld", FileInfo->fib_Size);
  232.                 Printf(" %-9s %9s %8s\n", Day, Date, Time);
  233.                 }
  234.             }
  235.         if (CheckBreak(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D,NULL))
  236.             {
  237.             Error = ERROR_BREAK;
  238.             break;
  239.             }
  240.         }
  241.         if (Error == NO_ERROR)
  242.             Error = IoErr();
  243.         }
  244.         RemDirEntry();
  245.         UnLock((BPTR) DirLock);
  246.         if (Error != ERROR_NO_MORE_ENTRIES)
  247.             break;
  248.         }
  249.     if (Tabs)
  250.         Puts("");
  251.     if (Error == ERROR_NO_MORE_ENTRIES && Found == TRUE)
  252.         Error = NO_ERROR;
  253.     FreeDirList();
  254.     FreeMem((STRPTR) FileInfo, sizeof(struct FileInfoBlock));
  255.     }
  256. else
  257.     Error  = ERROR_NO_MEM;
  258. switch(Error)
  259.     {
  260.     case NO_ERROR:
  261.         break;
  262.     case ERROR_INVALID_LOCK:
  263.         Puts("Invalid pattern or path name");
  264.         break;
  265.     case ERROR_NO_MEM:
  266.         Puts("No memory");
  267.         break;
  268.     case ERROR_NO_MORE_ENTRIES:
  269.         Puts("Search failed");
  270.         break;
  271.     case ERROR_OBJECT_NOT_FOUND:
  272.         Puts("Object not found");
  273.         break;
  274.     case ERROR_BREAK:
  275.         Puts("***Break");
  276.         break;
  277.     default:
  278.         Printf("Error %ld\n", Error);
  279.     }
  280. }
  281.  
  282. VOID MemCleanup()
  283. {
  284. }
  285.  
  286. VOID Break()
  287. {
  288.     Cleanup(RETURN_WARN,NULL,"***Break");
  289. }
  290.  
  291. VOID _main(Line)
  292. REGISTER STRPTR Line;
  293.  
  294. #define MAX_ARG 6
  295.  
  296. {
  297.     REGISTER LONG     ArgC;
  298.     STRPTR        Arg[MAX_ARG];
  299.     TEXT        EnvBuf[2];
  300.     _ONBREAK  = Break;
  301.  
  302.     Pr = (struct Process*)FindTask(NULL);
  303.     
  304.     if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
  305.             Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL);
  306.     
  307.  
  308.     for (ArgC = 0; ArgC < MAX_ARG; ++ArgC)
  309.         Arg[ArgC] = (STRPTR)NULL;
  310.     while (*Line > ' ') ++Line;
  311.  
  312.     if ((ArgC = GADS(++Line,
  313.             strlen(Line),
  314.             "Usage: Sf PAT <PathName|Pattern> [FILES=F] [DIRS=D] [QUICK=Q] [NOROOT=NR] [NOCOL=NC]",
  315.             Arg,
  316.             "PAT/A,FILES=F/S,DIRS=D/S,QUICK=Q/S,NOROOT=NR/S,NOCOL=NC/S"))<= 0)
  317.                 Cleanup(RETURN_FAIL,ERROR_LINE_TOO_LONG,Arg[0]);
  318.  
  319.     if(Getenv("dateformat",EnvBuf,2))
  320.     switch (EnvBuf[0]) {
  321.         case '1':
  322.         DateFormat = FORMAT_INT;
  323.         break;
  324.         case '2':
  325.         DateFormat = FORMAT_USA;
  326.         break;
  327.         case '3':
  328.         DateFormat = FORMAT_CDN;
  329.         break;
  330.      };
  331.  
  332.     if (ArgC > 0)
  333.         FindFile(Arg);
  334.  
  335.     Cleanup(NULL,NULL,NULL);
  336. }