home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 167 / c / where.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-08-18  |  13.9 KB  |  380 lines

  1. /***************************************************************
  2. *                                   *
  3. *       WHERE                           *
  4. *                                   *
  5. * The command line syntax is:                       *
  6. * where [starting directory]filename.ext               *
  7. *                                   *
  8. * Written by Mark S. Ackerman                       *
  9. *                                   *
  10. * Copyright 1984, 1985 by Mark S. Ackerman.  Permission is     *
  11. * granted for unlimited copies if not sold or otherwise           *
  12. * exchanged for gain.                           *
  13. *                                   *
  14. * 03/06/87 modified for Megamax C compiler for the Atari ST    *
  15. *       J.K.LaPeer                           *
  16. *                                   *
  17. ***************************************************************/
  18.  
  19.  
  20. /***************************************************************
  21. * The C header files                            *
  22. * These identify library routines like printf()               *
  23. ***************************************************************/
  24.  
  25. #include <stdio.h>    /* standard i/o                  */
  26. #include <osbind.h>    /* OS bindings                  */
  27. #include <string.h>    /* String Module bindings          */
  28.  
  29. /***************************************************************
  30. * Structure for MS-DOS date and time fields               *
  31. * See pages 4-6 and 4-7 of the DOS 2.1 technical           *
  32. * reference manual for more information                   *
  33. * This structure is used in the next structure definition      *
  34. ***************************************************************/
  35.  
  36. struct msdos_date 
  37.     {
  38.     unsigned ms_sec       : 5;    /* time in 2 sec. int (5 bits)*/
  39.     unsigned ms_min       : 6;    /* minutes (6 bits)          */
  40.     unsigned ms_hour   : 5;    /* hours (5 bits)          */
  41.     unsigned           : 0;
  42.     unsigned ms_day       : 5;    /* day of month (5 bits)      */
  43.     unsigned ms_month  : 4;    /* month (4 bits)          */
  44.     unsigned ms_year   : 7; /* year since 1980 (7 bits)   */
  45.      };
  46.  
  47. /***************************************************************
  48. * Definition of DOS Disk Transfer Area (DTA)                *
  49. ***************************************************************/
  50.  
  51. struct DTA
  52.     {
  53.     char     DTA_dosinfo[21];    /* used by DOS          */
  54.     char     DTA_attr;         /* file attribute byte   */
  55.     struct msdos_date DTA_date;  /* date struct. as above */
  56.     long     DTA_size;         /* file size          */
  57.     char     DTA_filename[14];   /* file name (w/o path)  */
  58.     };
  59.  
  60.  
  61. /***************************************************************
  62. *        Definitions of constants               *
  63. ***************************************************************/
  64.  
  65. #define no_type             0x00    /* no bits set on file attribute byte*/
  66. #define DirType             0x10    /* directory file bit on file 
  67.                     info word    */
  68. #define no_more_files     -13     /* DOS return code for 
  69.                     no more files             */
  70. #define end_of_string     '\0'     /* C uses a binary zero to 
  71.                       signal end of string    */
  72. #define backslash '\\'     /* the backslash character          */
  73.  
  74. char *month[] =    {
  75.         "Jan","Feb","Mar","Apr","May","Jun",
  76.         "Jul","Aug","Sep","Oct","Nov","Dec"
  77.         };
  78. char *time_of_day[2] = {"AM","PM"};
  79.  
  80.  
  81. /***************************************************************
  82. *        Define the type "filename"                *
  83. *            to be a string of 51 characters           *
  84. ***************************************************************/
  85.  
  86. /*typedef char filename[51];*/
  87.  
  88. /***************************************************************
  89. *                                   *
  90. * The following filename strings are used in the program:      *
  91. *                                   *
  92. *    check_string        filename to be searched for    *
  93. *                filename in the command line)  *
  94. *    directory_string    directory name to be searched  *
  95. *    newdirectory_string    directory name to be searched  *
  96. *                  on next recursive call       *
  97. *    current_string        temporary string for searching *
  98. *                  in a specific directory      *
  99. ***************************************************************/
  100.  
  101. /***************************************************************
  102. * Definition of any forward-referenced functions           *
  103. ***************************************************************/
  104.  
  105. char *DATE();
  106.  
  107. /***************************************************************
  108. *        Global variables                   *
  109. ***************************************************************/
  110.  
  111. char check_string[51];    /* this string "remembers" user input */
  112. char datestring[40];    /* print output string for dates      */
  113. long LretCode;        /* General Purpose long return code   */
  114.  
  115. /***************************************************************
  116. *        MAIN() -- the beginning of the code            *
  117. ***************************************************************/
  118.  
  119. main(argc,argv)
  120. int argc;
  121. char *argv[];
  122.     {
  123.     char directory_string[51];    /* directory to be searched   */
  124.     char *incoming_filename;    /* address of filename in 
  125.                    command line argument 
  126.                        (ie, the filename)          */
  127.     char *last_location;    /* address of last backslash in 
  128.                    command line argument      */
  129.     char *incoming_string;    /* address of 
  130.                    command line argument      */
  131.     int  last_directory_char;    /* last character
  132.                    in directory string      */
  133.  
  134. /********************************************************
  135. *    check number of incoming arguments              *        
  136. *    if incorrect, write an error message            *
  137. ********************************************************/
  138.                         
  139.     if (argc != 2)
  140.     printf
  141.     ("usage is:   WHERE [starting directory]filename.ext\n\n");
  142.     else
  143.     {
  144. /********************************************************
  145. * incoming_string is set to the first argument in the   *
  146. * command line                                          *
  147. * The incoming_string is then searched for the last     *
  148. * occurrence of a backslash to find the end of          *
  149. * the directory name.                                   *
  150. ********************************************************/
  151.  
  152. incoming_string = *(++argv);
  153. last_location = rindex(incoming_string,backslash);
  154.  
  155. /********************************************************
  156. * If there was not a backslash (and therefore the       *
  157. *     beginning directory is the root directory)        *
  158. * begin                                                 *
  159. *   copy command line argument into check_string        *
  160. *   copy root directory into directory_string           *
  161. * end                                                   *
  162. * else                                                  *
  163. * (if there was a backslash and therefore a beginning   *
  164. *     directory specified in the command line)          *
  165. * begin                                                 *
  166. *   set the incoming_filename to the next character     *
  167. *       past the backslash                              *
  168. *   copy the incoming_filename into check_string        *
  169. *   copy the command line argument into                 *
  170. *       directory_string                                *
  171. *   terminate directory_string just after the           *
  172. *    last backslash (therefore leaving only the      *
  173. *    the directory name in the string)               *
  174. * end                                                    *
  175. ********************************************************/
  176.                 
  177. if (last_location == NULL)
  178.     {
  179.     strcpy(check_string,incoming_string);
  180.     strcpy(directory_string,"\\");
  181.     }
  182. else
  183.     {
  184.     incoming_filename = last_location + 1;
  185.     strcpy(check_string,incoming_filename);
  186.     strcpy(directory_string,incoming_string);
  187.     last_directory_char = incoming_filename - incoming_string;
  188.     directory_string[last_directory_char] = end_of_string;
  189.                     }
  190. /********************************************************
  191. *        start 'er up                            *
  192. ********************************************************/
  193.         
  194. LOOK(directory_string);
  195. }
  196. return;
  197. }          
  198.  
  199.  
  200. LOOK(directory_string)
  201.  
  202. /********************************************************
  203. *    LOOK is the recursive procedure in WHERE        *
  204. *    It is called once for each subdirectory         *
  205. ********************************************************/
  206.  
  207. char *directory_string;
  208.     {
  209.     struct DTA current_DTA;  /* used to return data from DOS  */
  210.     char newdirectory_string[51]; /* the directory to be 
  211.                      searched on the next
  212.                      call to LOOK()           */
  213.     char current_string[51];      /* temporary filename 
  214.                      string for    searching for 
  215.                      directories          */
  216.  
  217. /********************************************************
  218. * Form current_string by copying directory_string and   *
  219. *    and then concatenating "*.*" to look through all   *
  220. *    files                                              *
  221. ********************************************************/
  222.  
  223.     strcpy(current_string,directory_string);
  224.     strcat(current_string,"*.*");
  225.  
  226. /********************************************************
  227. * Set the Disk Transfer Area in DOS to the current_DTA  *
  228. *    structure                                          *
  229. * Get the first subdirectory in this directory          *
  230. ********************************************************/
  231.  
  232.     SET_DTA(¤t_DTA);
  233.     GET_FIRST(current_string,DirType);
  234.  
  235. /********************************************************
  236. * while there are more subdirectories in this directory *
  237. * begin                                                 *
  238. *   double check for proper directories (see text)      *
  239. *   if a directory                                      *
  240. *   begin                                               *
  241. *     set up the newdirectory_string for the            *
  242. *     next call to LOOK (see text)                      *
  243. *     call LOOK                                         *
  244. *     reset Disk Transfer Address (see text)            *
  245. *   end                                                 *
  246. *   look for next directory                             *
  247. * end                                                   *
  248. ********************************************************/
  249.  
  250.     while (LretCode == 0)
  251.     {
  252.     if (current_DTA.DTA_attr == DirType &&
  253.        current_DTA.DTA_filename[0] != '.')
  254.         {
  255.         strcpy(newdirectory_string,directory_string);
  256.         strcat(newdirectory_string,current_DTA.DTA_filename);
  257.         strcat(newdirectory_string,"\\");
  258.         LOOK(newdirectory_string);
  259.         SET_DTA(¤t_DTA);
  260.         }
  261.     GET_NEXT();
  262.     }
  263.     
  264. /********************************************************
  265. * if there are no more subdirectories in this directory *
  266. *   look for files                                      *
  267. * else                                                  *
  268. *   print an error message                              *
  269. ********************************************************/
  270. /*
  271.     if (LretCode == no_more_files)
  272.     GET_FILES(directory_string,¤t_DTA);
  273.     else
  274.         printf("problem with looking thru %s\n",directory_string);
  275. */
  276.     GET_FILES(directory_string,¤t_DTA);
  277.     return;
  278.     }
  279.     
  280. GET_FILES(directory_string,current_DTA)
  281.  
  282. /********************************************************
  283. * GET_FILES                         *
  284. * is called once per directory to look for the         *
  285. *   actual files matching the search string        *
  286. ********************************************************/
  287.  
  288. char *directory_string;
  289. struct DTA *current_DTA;
  290.     {
  291.     char current_string[51];
  292.  
  293. /********************************************************
  294. * Form current_string by copying directory_string into  *
  295. *   it and then concatenating the check_string onto     *
  296. *   the end                                             *
  297. ********************************************************/
  298.  
  299.     strcpy(current_string,directory_string);
  300.     strcat(current_string,check_string);
  301.  
  302. /********************************************************
  303. * Get the first file that matches current_string        *
  304. ********************************************************/
  305.  
  306.     GET_FIRST(current_string,no_type);
  307.  
  308. /********************************************************
  309. * while there are more files that match the search      *
  310. *   string:                                             *
  311. * begin                                                 *
  312. *   print the file information                          *
  313. *   get the next file                                   *
  314. * end                                                   *
  315. ********************************************************/
  316.  
  317.     while (LretCode == 0)
  318.     {
  319. /*    printf(" %s  %s%s\n", DATE(&((*current_DTA).DTA_date)),
  320.                directory_string, (*current_DTA).DTA_filename);*/
  321.     printf(" %10ld  %s  %s%s\n", (*current_DTA).DTA_size,
  322.        DATE(&((*current_DTA).DTA_date)), directory_string,
  323.        (*current_DTA).DTA_filename);
  324.         GET_NEXT();
  325.     }
  326. /********************************************************
  327. * if error in looking for a file                        *
  328. *    print error message and return                     *
  329. ********************************************************/
  330. /*
  331.     if (LretCode != no_more_files)
  332.         printf("problem with looking for %s\n",current_string);
  333. */    return;
  334.     }
  335.  
  336.  
  337. GET_NEXT()
  338.     {
  339. /********************************************************
  340. * GET_NEXT does an interrupt 21h, function 4Fh          *
  341. ********************************************************/
  342.  
  343.     LretCode = Fsnext();
  344.     return;
  345.     }
  346.  
  347. SET_DTA(current_DTA)
  348.     struct DTA *current_DTA;
  349.     {
  350.  
  351.     Fsetdta(current_DTA);
  352.     return;
  353.     }
  354.  
  355. GET_FIRST(search_string,filetype)
  356.     char *search_string;
  357.     int filetype;
  358.     {
  359.  
  360.     LretCode = Fsfirst(search_string, filetype);
  361.     return;
  362.     }
  363.  
  364.     
  365. char *DATE(dateptr)
  366. struct msdos_date *dateptr;
  367.     {
  368. /********************************************************
  369. * DATE takes the date field from the current DTA        *
  370. *   structure and returns a string containing the       *
  371. *   information in formatted ASCII                      *
  372. ********************************************************/
  373.  
  374.     sprintf(datestring, "%02d-%02d-%2d  %02d:%02d %s",
  375.     dateptr->ms_month, dateptr->ms_day,
  376.     dateptr->ms_year+80, (dateptr->ms_hour)%12, 
  377.         dateptr->ms_min, time_of_day[((dateptr->ms_hour)/12)]);
  378.     return(datestring);
  379.     }
  380.