home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / unrm.rm / rm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.1 KB  |  137 lines

  1. /**            rm.c            **/
  2.  
  3. /** This program replaces 'rm' (it's assumed that this program is BEFORE 
  4.     /bin/rm in the path) and will ferret away copies of the files being 
  5.     removed to the directory /tmp/rm/<login>.  Files that are copied into 
  6.     /tmp/rm/* can be recalled by 'unrm filename'.  Every so often (probably 
  7.     midnight every night) a daemon should clear out the old files in the
  8.     /tmp/rm directory...
  9.  
  10.     (C) Copyright 1986, Dave Taylor, Hewlett-Packard Company
  11. **/
  12.  
  13. #include <stdio.h>
  14. #include <errno.h>
  15.  
  16. #define  real_rm    "/bin/rm"
  17. #define  RM_DIR        "/tmp/rm"
  18.  
  19. #define  ACCESS_MODE    04 & 02
  20. #define  DIR_ACCESS    04 & 01
  21.  
  22. #define  SLEN        80
  23.  
  24. #define  USERS_NAME    "LOGNAME"        /* "USER" in BSD */
  25.  
  26. extern int errno;
  27.  
  28. char *basename(), *getlogin(), *getenv();
  29.  
  30. main(argc, argv)
  31. int argc;
  32. char **argv;
  33. {
  34.     extern int optind;    /* for getopt */
  35.     char   buffer[SLEN], login_name[SLEN], dirname[SLEN], *cp;
  36.     int    c, oldumask; 
  37.  
  38.     while ((c = getopt(argc, argv, "rfi")) != EOF) {
  39.       switch (c) {
  40.         case 'r' : 
  41.         case 'f' : 
  42.         case 'i' : break;    /* just accept 'em... */
  43.         case '?' : exit(fprintf(stderr,"Usage: rm [-rfi] files\n"));
  44.       }
  45.     }
  46.  
  47.     if (strlen(argv[optind]) == 0)
  48.       exit(0);
  49.  
  50.     /* is the top level /tmp directory available??? */
  51.  
  52.     if (access(RM_DIR, DIR_ACCESS)) {
  53.       sprintf(buffer,"mkdir %s; chmod 777 %s", RM_DIR, RM_DIR);
  54.       if (system(buffer) != 0) {
  55.         printf("'%s' failed!!\n", buffer);
  56.         exit(1);
  57.       }
  58.     }
  59.  
  60.     /* now get the users login name... */
  61.  
  62.     if ((cp = getenv(USERS_NAME)) == NULL)
  63.       strcpy(login_name, getlogin());
  64.     else
  65.       strcpy(login_name, cp);
  66.  
  67.     /* let's see if THAT directory is hangin' around... */
  68.  
  69.     sprintf(dirname, "%s/%s", RM_DIR, login_name);
  70.  
  71.     if (access(dirname, DIR_ACCESS)) {
  72.       sprintf(buffer,"mkdir %s; chmod 700 %s", dirname, dirname);
  73.       if (system(buffer) != 0) {
  74.         printf("'%s' failed!!\n", buffer);
  75.         exit(1);
  76.       }
  77.     }
  78.  
  79.     oldumask = umask(077);
  80.     while (strlen(argv[optind]) > 0) {
  81.       if (access(basename(argv[optind]), ACCESS_MODE) == 0)
  82.         save_copy_of(dirname, argv[optind]);
  83.       optind++;
  84.     }
  85.     (void) umask(oldumask);
  86.  
  87.     execv(real_rm, argv);
  88.     
  89.     fprintf(stderr,"rm: error %d exec'ing!\n", errno);
  90. }
  91.  
  92. char *basename(string)
  93. char *string;
  94. {
  95.     /** returns the basename of the file specified in string **/
  96.  
  97.     static   char *buff;
  98.  
  99.     buff = string + strlen(string); /* start at last char */
  100.     
  101.     while (*buff != '/' && buff > string) buff--;
  102.  
  103.     return( (char *) (*buff == '/'? ++buff : buff));
  104. }
  105.  
  106. save_copy_of(dirname, filename)
  107. char *dirname, *filename;
  108. {
  109.     /** Try to link filename to dirname, if that fails, copy it
  110.         bit by bit... **/
  111.  
  112.     char newfname[80];
  113.  
  114.     sprintf(newfname,"%s/%s", dirname, basename(filename));
  115.  
  116.     (void) unlink(newfname);    /* blow it away if already there! */
  117.  
  118.     if (link(filename, newfname) != 0) {
  119.       FILE *infile, *outfile;    
  120.       int   c;
  121.       
  122.       if ((infile = fopen(filename, "r")) == NULL)
  123.         exit(fprintf(stderr, "rm: can't read file '%s' to save a copy!\n", 
  124.          filename));
  125.  
  126.       if ((outfile = fopen(newfname, "w")) == NULL)
  127.         exit(fprintf(stderr, "rm: can't write to file '%s'!\n",
  128.          newfname));
  129.  
  130.       while ((c = getc(infile)) != EOF)
  131.         putc(c, outfile);
  132.       
  133.       fclose(infile);
  134.       fclose(outfile);
  135.     }
  136. }
  137.