home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / derez / derez.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-30  |  4.3 KB  |  162 lines

  1. /* This program archives and removes all files on /u0
  2. that have not been accessed in 180 days.
  3.     */
  4.  
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <sys/file.h>
  8. #include <strings.h>
  9.  
  10. #define MAXLEN 10240
  11. #define USAGE "derez [-t days] [dir1 dir2 dir3 ...]\n"
  12.  
  13. #include <stdio.h>
  14.  
  15. main(argc, argv)
  16. int argc;
  17. char **argv;
  18. {
  19.     FILE *fptr;
  20.     struct stat statbuf;
  21.     char filename[MAXLEN];
  22.     char cmd[MAXLEN];
  23.     char dirlist[MAXLEN];
  24.     int since;
  25.  
  26.     dirlist[0] = NULL;
  27.     since = 180;
  28.  
  29.  
  30.     /* Check for the existence and access permissions on the MORGUE.
  31.         */
  32.     if(stat("MORGUE", &statbuf)) {
  33.         perror("derez: MORGUE");
  34.         exit(1);
  35.     }
  36.     if(!(statbuf.st_mode & S_IFDIR)) {
  37.         fprintf(stderr, "derez: MORGUE is not a directory\n");
  38.         exit(1);
  39.     }
  40.     if(access("MORGUE", R_OK | W_OK | X_OK)) {
  41.         fprintf(stderr, "derez: The MORGUE must have read, write and execute perms\n");
  42.         exit(1);
  43.     }
  44.  
  45.     if(argc > 1) {
  46.         if(strcmp(argv[1], "-t") == 0) {
  47.             if(argc < 3) {
  48.                 fprintf(stderr, USAGE);
  49.                 exit(1);
  50.             }
  51.             if(sscanf(argv[2], "%d", &since) != 1) {
  52.                 fprintf(stderr, "derez: bad arg for -t option %s\n", argv[2]);
  53.                 exit(1);
  54.             }
  55.             if(since < 1 || since > 1000) {
  56.                 fprintf(stderr, "derez: bad value for -t argument\n");
  57.                 exit(1);
  58.             }
  59.             argv += 2;
  60.             argc -= 2;
  61.         }
  62.         while(argc > 1) {
  63.             if((strncmp(argv[1], "/", strlen("/")) == 0) || (strncmp(argv[1], "../", strlen("../")) == 0)) {
  64.                 fprintf(stderr, "derez: Directories must be relative to .\n");
  65.                 exit(1);
  66.             }
  67.             if(lstat(argv[1], &statbuf)) {
  68.                 fprintf(stderr, "The directory %s must exist\n", argv[1]);
  69.                 exit(1);
  70.             }
  71.             if(statbuf.st_mode & S_IFDIR) {
  72.                 if(dirlist[0] != NULL)
  73.                     strcat(dirlist, " ");
  74.                 strcat(dirlist, argv[1]);
  75.                 argv += 1;
  76.                 argc -= 1;
  77.             }
  78.             else {
  79.                 fprintf(stderr, "derez: %s is not a directory\n", argv[1]);
  80.                 exit(1);
  81.             }
  82.         }
  83.     }
  84.     /* We currently only derez files with 1 link as derez would
  85.     break up two links to the same file into seperate files.
  86.     We will have to steal code from tar to do an internal link table
  87.     and drop the use of tar completely.
  88.         */
  89.     sprintf(cmd, "find %s -type f -links 1 -atime +%d -print > MORGUE/DEREZ",
  90.         (dirlist[0] == NULL ? "." : dirlist), since);
  91.  
  92.     printf("%s\n", cmd);
  93.     if(system(cmd) != 0) {
  94.         fprintf(stderr, "derez: The attempt to create MORGUE/DEREZ failed\n");
  95.         exit(1);
  96.     }
  97.     if((fptr = fopen("MORGUE/DEREZ", "r")) == NULL) {
  98.         fprintf(stderr, "Open of MORGUE/DEREZ for reading failed\n");
  99.         exit(1);
  100.     }
  101.     while(fgets(filename, MAXLEN, fptr) != NULL) {
  102.         char *rightslash;
  103.         /* Kill off the newline. */
  104.         if(filename[strlen(filename) - 1] != '\n') {
  105.             fprintf(stderr, "missing \\n on %s\n", filename);
  106.             continue;
  107.         }
  108.         filename[strlen(filename) - 1] = NULL;
  109.  
  110.         /* If the file path name is too long we don't want
  111.         to see the error message from tar.
  112.             */
  113.         if(strlen(filename) > 99)
  114.             continue;
  115.  
  116.         /* If the file basename is of the form .* we want to
  117.         leave it alone to prevent removal of someones login
  118.         directory or setup files.  Of course if you take this
  119.         code out you get automatic removal of directories
  120.         associated with inactive accounts.
  121.             */
  122.         if((rightslash = rindex(filename, '/')) != NULL) {
  123.             if(rightslash[1] == '.')
  124.                 continue;
  125.         }
  126.         
  127.         if(
  128.             /* We don't want to mess with files already in the MORGUE.
  129.                 */
  130.             (strncmp(filename, "./MORGUE/", strlen("./MORGUE/")) != 0)
  131.             && (strncmp(filename, "MORGUE/", strlen("MORGUE/")) != 0)
  132.             /* The lost+found directory is a sacred system item.
  133.                 */
  134.             && (strncmp(filename, "./lost+found/", strlen("./lost+found/")) != 0)
  135.             && (strncmp(filename, "lost+found/", strlen("lost+found/")) != 0)
  136.             /* If we were to enmorgue a file named DEREZ, we
  137.             would overwrite the list of files to move.
  138.                 */
  139.             && (strncmp(filename, "./DEREZ") != 0)
  140.             && (strcmp(filename, "DEREZ") != 0)
  141.         ){
  142.             sprintf(cmd, "tar cf - %s | (cd MORGUE; tar xpf -)", filename);
  143.             if(system(cmd) == 0) {
  144.                 fprintf(stderr, "enmorgue of %s succeeded\n", filename);
  145.                 unlink(filename);
  146.                 /* If it was the last file in the directory
  147.                 we also want to remove the directory.
  148.                     */
  149.                 while(strlen(filename) > 0 && filename[strlen(filename) - 1] != '/') {
  150.                     filename[strlen(filename) - 1] = NULL;
  151.                 }
  152.                 filename[strlen(filename) - 1] = NULL;
  153.                 rmdir(filename);
  154.             }
  155.             else {
  156.                 fprintf(stderr, "enmorgue of %s FAILED, file removal was inhibited\n", filename);
  157.             }
  158.         }
  159.     }
  160.     fclose(fptr);
  161. }
  162.