home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / dirutl / di11.arc / DIMAIN.C < prev    next >
Text File  |  1987-11-29  |  8KB  |  212 lines

  1. /* DI : Directory listing utility.   By  John H. DuBois III.   v1.1.
  2.    Last rev 11/29/87.   Full documentation in DI.DOC.
  3.    Searches directories and prints matching files.
  4.    Multiple file specifications can be given.
  5.    Any filespec can include wildcards in both filename and path.
  6.    Recursive search of directories can be specified.
  7.    Attributes of files to search for are given in and-terms; multiple and-terms
  8.     can be given and files which match any of them will be printed.
  9.    Files found in each directory can be sorted according to various criteria
  10.     before groups of files with non-differing criteria are sorted by filename.
  11.    Listing can be printed in long form, wide form, or with full path of files.
  12.    Pause after each page can be specified.
  13.    Printing of free space on device can be toggled off.
  14.    Printing of headers can be toggled off.
  15.    Total space used by the files listed can be printed.
  16.    Initial listing specifications and search attributes can be specified by an
  17.     environment variable.   */
  18.  
  19. #include <stdio.h>
  20. #include <dir.h>
  21. #include <dos.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <conio.h>
  25. #include <io.h>
  26. #include "di.h"
  27.  
  28. main(int argc,char *argv[])
  29. {
  30. NameNode *Files,    /* Linked list of directories to print */
  31. *Temp;        /* Points to entry to be disposed of */
  32. int Attribs[MAX_ATTS];
  33. int Cnt;    /* Number of parameters given in environment var + 1 */
  34. ListType ListSpec;
  35. static char *Defaults[3] = {"","*.*","/LI5HSV"};    /* Default listing:
  36.  list all files in current dir; list Long; sort by dIr attrib; when listing
  37.  wide, print 5 entries per line; print all entries except those with attribs
  38.  Hidden, System, or Volume label. */
  39. EntryListType EntryList;    /* Matching files found in a dir */
  40. char *Vars[80];        /* Value of env var */
  41.  
  42.    setcbrk(1);    /* Turn on cntrl-brk checking at all DOS interupts */
  43.    More(-1);    /* Initialize More() to disabled */
  44.    Files = NULL;    /* Initialize Files to null list */
  45.    ListSpec.PrintFree = TRUE;   /* Make free space printing the default */
  46.    ListSpec.PrintHeaders = TRUE;    /* Make header printing the default */
  47.    ListSpec.RecSearch = FALSE;    /* Make no recursive listing the default */
  48.    GetArgs(3,Defaults,Attribs,&ListSpec,&Files);    /* Set up internal
  49.     defaults for search attribs, list specs, and files to list */
  50.    if (GetEnvParams(&Cnt,Vars,"DI")) {    /* If "DI" env var exists, get
  51.     new defaults from it */
  52.       GetArgs(Cnt,Vars,Attribs,&ListSpec,&Files);
  53.       free(Vars[0]);    /* Free copied env var */
  54.    }
  55.    GetArgs(argc,argv,Attribs,&ListSpec,&Files);    /* Convert command line args
  56.        to search attribs, list specs, and file specs */
  57.    if (!isatty(1)) /* If stdout is redirected, turn of More if it was
  58.                enabled */
  59.       More(-1);
  60.    if (ListSpec.PrintHeaders)
  61.       PrintHeader(Files,ListSpec.PrintFree);    /* Print volume labels and
  62.            possibly free space for all drives given in file specs */
  63.    while (Files != NULL) {    /* For each filespec given */
  64.       /* Get all matching fls */
  65.       GetEntries(&EntryList,Attribs,Files -> Name,!ListSpec.RecSearch);
  66.       if (EntryList.NumEnts > 1)    /* If at least two matching files were
  67.                     found, sort list as specified */
  68.          SortList(&EntryList,ListSpec.Sort);
  69.       PrintList(&EntryList,&ListSpec,Files -> Name); /* Print list */
  70.       Temp = Files;    /* Discard list node */
  71.       free(Files);
  72.       Files = Temp -> Next;
  73.    }
  74. }
  75.  
  76. More(int Lines)
  77. /* Pauses and waits for a key to be struck when MORE_ROWS lines have been
  78.    printed.  A call with Lines = 0 resets line count to 0 and enables More.
  79.    A call with Lines = -1 disables More.  A call with a positive number
  80.    increments the line count by that amount. If More is disabled, it will
  81.    return from all calls without pausing until it is called with 0.
  82.    More() is called each time new lines are printed, with Lines set to the
  83.    number of lines printed. If a number of lines is printed between calls that
  84.    is larger than (screen height - MORE_ROWS), lines may be lost (scrolled out
  85.    without pausing).  If, when More() pauses for a key to be hit, <space>
  86.    is pressed, the line count will be set to 0 and More will return.  If
  87.    any other key except q is hit, the line count will be set to MORE_ROWS - 1
  88.    and More will return.  In this case, the next time it is called it will
  89.    pause again (unless it is called with 0). If 'q' is pressed, the program
  90.    will be terminated with exit status - 1.  All output is directly to
  91.    screen.  More returns its enable status (-1 if enabled, else 0) which
  92.    is the inverse of the codes used to enable/disable More.  A call
  93.    with a negative number other than -1 for Lines is a null call and will
  94.    have no effect; it will only return the enable status.  Such a call can
  95.    therefore be used to return a number which will toggle the enable status
  96.    of More if it is called with it */
  97. {
  98. static int Line,    /* Line count */
  99. Enabled = FALSE;    /* Whether More is enabled */
  100.  
  101.    if (Lines > -2)
  102.       switch (Lines) {
  103.          case 0 :    Line = 0;
  104.             Enabled = TRUE;
  105.             break;
  106.          case -1 :    Enabled = FALSE;
  107.             break;
  108.          default :
  109.             if (Enabled && (Line += Lines) >= MORE_ROWS) { /* Print message
  110.                                     to screen & pause */
  111.                fputs("--More--",stderr);
  112.                switch (getch()) {
  113.                   case ' ' :    Line = 0;
  114.                 break;
  115.                   case 'q' :
  116.                   case 'Q' :    fputs("\b\b\b\b\b\b\b\bQuit    \n",stderr);
  117.                 exit(1);
  118.                   default  :    Line = MORE_ROWS - 1;
  119.                }
  120.                fputs("\b\b\b\b\b\b\b\b        \b\b\b\b\b\b\b\b",stderr);
  121.                             /* Erase message */
  122.             }
  123.    }
  124.    return (Enabled);
  125. }
  126.  
  127. char *Insert(char *Target,char *Source,int Pos)
  128. /* Inserts string Source into string Target at position Pos. If the length of
  129.    Target is less than Pos, Source is appended to Target. */
  130. {
  131. unsigned SLen,TLen;    /* Length of source and target strings */
  132.  
  133.    SLen = strlen(Source);
  134.    TLen = strlen(Target);
  135.    if (TLen < Pos)
  136.       strcat(Target,Source);
  137.    else {
  138.       memcpy(Target + Pos + SLen,Target + Pos,TLen - Pos + 1);    /* Make room
  139.                     in target string for source string */
  140.       memcpy(Target + Pos,Source,SLen); /* Copy source string to targ string */
  141.    }
  142.    return(Target);
  143. }
  144.  
  145. char *AttribWtoS(char A)
  146. /* Converts an attibute word (A) to a string of characters representing the
  147.    word's active attributes, puts the string in a static buffer, and
  148.    returns a pointer to the buffer */
  149. {
  150. static char Attribs[7];        /* Attribute character buffer */
  151. static char Convert[] = "RHSVDA";    /* Ordered attribute list */
  152. int I,    /* Which attribute is being tested */
  153. J,    /* Index to buffer */
  154. Mask;    /* Bit mask to get attribute flag */
  155.  
  156.    Mask = 1;    /* Start with bit 0 */
  157.    J = 0;
  158.    for (I = 0; I < 6; I++) {
  159.       if (A & Mask)    /* Add attribute to buffer */
  160.          Attribs[J++] = Convert[I];
  161.       Mask <<= 1;    /* Check next attribute */
  162.    }
  163.    Attribs[J] = '\0';    /* Terminate string */
  164.    return(Attribs);
  165. }
  166.  
  167. void *MallocT(unsigned Size)
  168. /* Calls malloc() to allocate a block of memory of size Size and checks
  169.    whether there was enough memory. Exits if not, otherwise returns a
  170.    pointer to the block */
  171. {
  172. void *Temp;
  173.  
  174.    Temp = (void *) malloc(Size);
  175.    if (Temp == NULL) {
  176.       fputs("Error: Not enough memory.",stderr);
  177.       exit(2);
  178.    }
  179.    return(Temp);
  180. }
  181.  
  182. void *CallocT(unsigned NElem,unsigned Size)
  183. /* Calls calloc() to allocate a block of memory for NElem elements of size
  184.    Size and checks whether there was enough memory. Exits if not, otherwise
  185.    returns a pointer to the block */
  186. {
  187. void *Temp;
  188.  
  189.    Temp = (void *) calloc(NElem,Size);
  190.    if (Temp == NULL) {
  191.       fputs("Error: Not enough memory.",stderr);
  192.       exit(2);
  193.    }
  194.    return(Temp);
  195. }
  196.  
  197. void *ReallocT(void *Ptr,unsigned Size)
  198. /* Calls Realloc() to reallocate the block pointed to by Ptr to size Size
  199.    and checks whether there was enough memory. Exits if not, otherwise
  200.    returns a pointer to the block */
  201. {
  202. void *Temp;
  203.  
  204.    Temp = (void *) realloc(Ptr,Size);
  205.    if (Temp == NULL) {
  206.       fputs("Error: Not enough memory.",stderr);
  207.       exit(2);
  208.    }
  209.    return(Temp);
  210. }
  211.  
  212.