home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / T_CLEAN.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  9KB  |  298 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  Remove all files older than a given date from the current directory
  5. **  and (optionally) all subdirectories
  6. **
  7. **  public domain by Bob Stout
  8. **
  9. **  uses SCALDATE.C & FTIME.C from SNIPPETS
  10. **  also uses TODAY.C & FDATE.C from SNIPPETS
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <io.h>
  17. #include <dos.h>
  18. #include <ctype.h>
  19. #include <time.h>
  20. #include "sniptype.h"
  21. #include "dirport.h"
  22. #include "ftime.h"
  23. #include "scaldate.h"
  24. #if defined(MSDOS) || defined(__MSDOS__)
  25.  #include "unistd.h"
  26. #else
  27.  #include <unistd.h>
  28. #endif
  29.  
  30. #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__))
  31.  /* Make FP_xxx macros lvalues as in older versions */
  32.  #undef FP_SEG
  33.  #undef FP_OFF
  34.  #define FP_SEG(fp)    ((unsigned)((unsigned long)(fp) >> 16))
  35.  #define FP_OFF(fp)    ((unsigned)(fp && 0xffff))
  36. #endif
  37.  
  38. #define show(s) fputs((s), stderr)
  39.  
  40. /*
  41. **  Switches and globals
  42. */
  43.  
  44. Boolean_T recurse = False_, gobble = False_;
  45. Boolean_T ignore = False_, noaction = False_;
  46.  
  47. long kill_date = 0L;
  48. FILE *log = NULL;
  49. long file_date;
  50.  
  51. /*
  52. **  Local prototypes
  53. */
  54.  
  55. static void usage(Boolean_T errstat);
  56. static void clean_dir(char *path);
  57. static void do_dir(char *path);
  58. static void RMfile(char *fname);
  59. static void RMdir(char *dname);
  60. static int  log_printf(char *str, char *arg);
  61.  
  62. /*
  63. **  T_CLEAN - Deletes all files and (optionally) subdirectories
  64. */
  65.  
  66. int main(int argc, char *argv[])
  67. {
  68.       int i, j, span;
  69.       Boolean_T found_dir = False_;
  70.       void (*clean_func)(char *) = clean_dir;
  71.  
  72.       for (i = 1; i < argc; ++i)          /* Check for switches         */
  73.       {
  74.             if (NULL == strchr("-/", *argv[i]))
  75.                   continue;               /* Assume it's a filename     */
  76.             for (j = 1; argv[i][j] ; ++j) /* Traverse nested switches   */
  77.             {
  78.                   switch (toupper(argv[i][j]))
  79.                   {
  80.                   case 'R':
  81.                         clean_func = do_dir;
  82.                         break;
  83.  
  84.                   case 'G':
  85.                         gobble = True_;
  86.                         break;
  87.  
  88.                   case 'I':
  89.                         ignore = True_;
  90.                         break;
  91.  
  92.                   case 'N':
  93.                         noaction = True_;
  94.                         break;
  95.  
  96.                   case '?':
  97.                         fputs("*** Help ***\n", stderr);
  98.                         usage(False_);
  99.                         break;
  100.  
  101.                   case 'L':
  102.                         if (0 == strlen(&argv[i][++j]))
  103.                               log = stdout;
  104.                         else
  105.                         {
  106.                               log = fopen(strupr(&argv[i][j]), "w");
  107.                               if (NULL == log)
  108.                               {
  109.                                     fprintf(stderr, "*** Unable to open "
  110.                                           "logfile, %s\n", &argv[i][j]);
  111.                                     return Error_;
  112.                               }
  113.                         }
  114.                         j += strlen(&argv[i][j]) - 1; /* End of switch  */
  115.                         break;
  116.  
  117.                   case 'T':
  118.                         if (0 == strlen(&argv[i][++j]))
  119.                         {
  120.                               fputs("*** No time specified ***\n", stderr);
  121.                               usage(Error_);                /* Oops     */
  122.                         }
  123.                         span = atoi(&argv[i][j]);
  124.                         kill_date = today() - (long)(span);
  125.                         j += strlen(&argv[i][j]) - 1; /* End of switch  */
  126.                         break;
  127.  
  128.                   default:
  129.                         fprintf(stderr, "*** Bad switch - %c ***",
  130.                               argv[i][j]);
  131.                         usage(Error_);
  132.                   }
  133.             }
  134.       }
  135.       if (0L == kill_date)
  136.             kill_date = today() - 14L;
  137.  
  138.       for (i = 1; i < argc; ++i)          /* Scan filenames             */
  139.       {
  140.             if (strchr("/-", *argv[i]))
  141.                   continue;
  142.             found_dir = True_;
  143.             clean_func(argv[i]);
  144.       }
  145.       if (!found_dir)
  146.       {
  147.             fputs("*** No directory specified ***\n", stderr);
  148.             usage(True_);
  149.       }
  150.       return EXIT_SUCCESS;
  151. }
  152.  
  153. /*
  154. **  Tell 'em they messed up
  155. */
  156.  
  157. static void usage(Boolean_T errstat)
  158. {
  159.       if (errstat)
  160.             fputc('\a', stderr);
  161.       show("Usage: T_CLEAN directory [...directory] [-tN] [-l[LOGFILE]] "
  162.             "[-rgin?]\n");
  163.       show("switches: -tN          Remove only files older than N days\n"
  164.             "                       (default = 14 days)\n");
  165.       show("          -l[LOGFILE]  Create named log file or (default) log to "
  166.             "the console\n");
  167.       show("          -r           Recurse subdirectories\n");
  168.       show("          -g           Gobble (delete) empty subdirectories\n");
  169.       show("          -i           Ignore special file attributes "
  170.             "(CAUTION!)\n");
  171.       show("          -n           No Action, display/log proposed "
  172.             "deletions\n");
  173.       show("          -?           Display help (this message)\n");
  174.       exit(errstat);
  175. }
  176.  
  177. /*
  178. **  Clean all files from a directory
  179. */
  180.  
  181. static void clean_dir(char *path)
  182. {
  183.       char rmpath[FILENAME_MAX], *rmfile;
  184.       DOSFileData fbuf;
  185.       unsigned attrib = (ignore) ? _A_ANY : 0;
  186.  
  187.       strcpy(rmpath, path);
  188.       if ('\\' != LAST_CHAR(rmpath))
  189.             strcat(rmpath, "\\");
  190.       rmfile = &rmpath[strlen(rmpath)];
  191.       strcpy(rmfile, "*.*");
  192.       if (0 == FIND_FIRST(rmpath, attrib, &fbuf)) do
  193.       {
  194.             strcpy(rmfile, ff_name(&fbuf));
  195.             if (0 != getdatef(rmpath, &file_date))
  196.             {
  197.                   log_printf("Unable to get date of %s\n", rmpath);
  198.                   continue;
  199.             }
  200.             if (ignore)
  201.             {
  202.                   union REGS regs;
  203.                   struct SREGS sregs;
  204.  
  205.                   regs.x.ax = 0x4300;
  206.                   regs.x.dx = FP_OFF((char FAR *)rmpath);
  207.                   segread(&sregs);
  208.                   sregs.ds  = FP_SEG((char FAR *)rmpath);
  209.                   intdosx(®s, ®s, &sregs);
  210.                   if (!regs.x.cflag)
  211.                   {
  212.                         regs.x.ax  = 0x4301;
  213.                         regs.x.cx &= ~(_A_RDONLY | _A_HIDDEN | _A_SYSTEM);
  214.                         intdosx(®s, ®s, &sregs);
  215.                         if (regs.x.cflag)
  216.                               log_printf("Unable to ignore attributes "
  217.                                     "of %s\n", rmpath);
  218.                   }
  219.             }
  220.             if (kill_date > file_date)
  221.                   RMfile(rmpath);
  222.       } while (0 == FIND_NEXT(&fbuf));
  223. }
  224.  
  225. /*
  226. **  Process directories
  227. */
  228.  
  229. static void do_dir(char *path)
  230. {
  231.       char search[FILENAME_MAX], new[FILENAME_MAX];
  232.       DOSFileData ff;
  233.  
  234.       strcpy(search, path);
  235.       if ('\\' != LAST_CHAR(search))
  236.             strcat(search, "\\");
  237.       strcat(search, "*.*");
  238.       if (Success_ == FIND_FIRST(search, _A_ANY, &ff)) do
  239.       {
  240.             if (ff.attrib & _A_SUBDIR && '.' != *ff_name(&ff))
  241.             {
  242.                   strcpy(new, path);
  243.                   if ('\\' != LAST_CHAR(new))
  244.                         strcat(new, "\\");
  245.                   strcat(new, ff_name(&ff));
  246.                   do_dir(new);
  247.             }
  248.       } while (Success_ == FIND_NEXT(&ff));
  249.       clean_dir(path);
  250.       if (gobble)
  251.             RMdir(path);
  252. }
  253.  
  254. /*
  255. **  File removal function - includes noaction switch and logging
  256. */
  257.  
  258. static void RMfile(char *fname)
  259. {
  260.       unsigned yr, mo, dy;
  261.  
  262.       if (!noaction)
  263.             remove(fname);
  264.       if (log)
  265.       {
  266.             scalar_to_ymd(file_date, &yr, &mo, &dy);
  267.             fprintf(log, "%02d/%02d/%04d: %s\n", mo, dy, yr, fname);
  268.       }
  269.       else  fprintf(stderr, "Deleting %s\n", fname);
  270. }
  271.  
  272. /*
  273. **  Directory removal function - includes noaction switch and logging
  274. */
  275.  
  276. static void RMdir(char *dname)
  277. {
  278.       if (!noaction)
  279.             rmdir(dname);
  280.       if (log)
  281.             fprintf(log, "Attempting to remove directory %s\n", dname);
  282. }
  283.  
  284. /*
  285. **  Error logging printf()
  286. */
  287.  
  288. static int log_printf(char *str, char *arg)
  289. {
  290.       FILE *out;
  291.  
  292.       if (log)
  293.             out = log;
  294.       else  out = stderr;
  295.  
  296.       return fprintf(out, str, arg);
  297. }
  298.