home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Utilities / vmount-0.6a-I / src / vumount.c < prev   
Encoding:
C/C++ Source or Header  |  1997-05-14  |  4.2 KB  |  171 lines

  1. /*
  2.  * Name: vumount.c
  3.  * Description: Unmount the given vmounted volume
  4.  * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
  5.  * Date: 1997-04-30
  6.  * Copyright: GNU-GPL
  7.  * Tabsize: 4
  8.  */
  9.  
  10. #include <libc.h>
  11. #include <errno.h>
  12. #include <mntent.h>
  13. #include "my_defines.h"
  14.  
  15. /* ------------------------------------------------------------------------- */
  16.  
  17. extern int    errno;
  18. static char    *my_name;
  19.  
  20. /* ------------------------------------------------------------------------- */
  21.  
  22. static void    remove_entry(char *path)
  23. {
  24. FILE            *fpout, *fpin;
  25. struct mntent    *ent;
  26. char            tempfile[2048];
  27. int                changed = 0;
  28.  
  29.     sprintf(tempfile, "%s-%d.tmp", MOUNTED, getpid());
  30.     if((fpin = setmntent(MOUNTED, "r")) == NULL){
  31.         fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
  32.                                         my_name, MOUNTED, strerror(errno));
  33.         return;
  34.     }else{
  35.         if((fpout = setmntent(tempfile, "w")) == NULL){
  36.             fprintf(stderr, "%s: error creating ->%s<-: %s\n",
  37.                                         my_name, tempfile, strerror(errno));
  38.             endmntent(fpin);
  39.             return;
  40.         }
  41.         while((ent = getmntent(fpin)) != NULL){
  42.             if(strcmp(ent->mnt_dir, path) != 0)
  43.                 addmntent(fpout, ent);
  44.             else
  45.                 changed = 1;
  46.         }
  47.         endmntent(fpout);
  48.         endmntent(fpin);
  49.         if(changed){
  50.             if(rename(tempfile, MOUNTED) != 0){
  51.                 fprintf(stderr, "%s: error moving temp file ->%s<- to "
  52.                                     "->%s<-\n", my_name, tempfile, MOUNTED);
  53.                 unlink(tempfile);
  54.             }
  55.         }else
  56.             unlink(tempfile);
  57.     }
  58. }
  59.  
  60. /* ------------------------------------------------------------------------- */
  61.  
  62. static int    umount_dir(char *path)
  63. {
  64. FILE            *fpin;
  65. struct mntent    *ent;
  66. int                i, pid, rval = 0, found_any = 0;
  67.  
  68.     if((fpin = setmntent(MOUNTED, "r")) == NULL){
  69.         fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
  70.                                         my_name, MOUNTED, strerror(errno));
  71.         return -1;
  72.     }else{
  73.         while((ent = getmntent(fpin)) != NULL){
  74.             if(strcmp(ent->mnt_dir, path) == 0){
  75.                 found_any = 1;
  76.                 if(sscanf(ent->mnt_type, "vmount-%d", &pid) == 1){
  77.                     if(unmount(path) != 0){
  78.                         fprintf(stderr, "%s: cannot unmount ->%s<-: %s\n",
  79.                                     my_name, ent->mnt_dir, strerror(errno));
  80.                         rval = -1;
  81.                     }else{
  82.                         if(fork() != 0){    /* parent */
  83.                             kill(pid, 1);
  84.                             for(i=0; kill(pid, 0) == 0 && i < 600; i++){
  85.                                 usleep(100000);
  86.                             }    /* wait up to 60s for terminate */
  87.                         }else{
  88.                             signal(SIGHUP, SIG_IGN);
  89.                             signal(SIGTERM, SIG_IGN);
  90.                             signal(SIGTSTP, SIG_IGN);
  91.                             signal(SIGQUIT, SIG_IGN);
  92.                             signal(SIGPIPE, SIG_IGN);
  93.                             signal(SIGURG, SIG_IGN);
  94.                             signal(SIGCONT, SIG_IGN);
  95.                             signal(SIGCHLD, SIG_IGN);
  96.                             signal(SIGTTIN, SIG_IGN);
  97.                             signal(SIGTTOU, SIG_IGN);
  98.                             signal(SIGIO, SIG_IGN);
  99.                             signal(SIGWINCH, SIG_IGN);
  100. /*
  101.  * Note: This is an evil hack. Workspace overwrites /etc/mtab to what it
  102.  * thinks is correct, but that is wrong if more than one volume was mounted
  103.  * by an *.util program. So we wait several seconds (until Workspace has
  104.  * done its evil things) and overwrite mtab with what _we_ think is correct.
  105.  */
  106.                             sleep(4);
  107.                             lock_mtab();
  108.                             remove_entry(path);
  109.                             unlock_mtab();
  110.                             exit(0);
  111.                         }
  112.                     }
  113.                 }else{
  114.                     fprintf(stderr, "%s: type ->%s<- not mounted by vmount\n",
  115.                                                     my_name, ent->mnt_type);
  116.                     rval = -1;
  117.                 }
  118.             }
  119.         }
  120.         endmntent(fpin);
  121.         if(!found_any){
  122.             fprintf(stderr, "%s: directory ->%s<- not found in mtab\n",
  123.                                                             my_name, path);
  124.         }
  125.     }
  126.     return rval;
  127. }
  128.  
  129. /* ------------------------------------------------------------------------- */
  130.  
  131. static void    print_all(void)
  132. {
  133. FILE            *fpin;
  134. struct mntent    *ent;
  135. int                pid;
  136.  
  137.     if((fpin = setmntent(MOUNTED, "r")) == NULL){
  138.         fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
  139.                                         my_name, MOUNTED, strerror(errno));
  140.         return;
  141.     }else{
  142.         while((ent = getmntent(fpin)) != NULL){
  143.             if(sscanf(ent->mnt_type, "vmount-%d", &pid) == 1){
  144.                 printf("%s\n", ent->mnt_dir);
  145.             }
  146.         }
  147.         endmntent(fpin);
  148.     }
  149. }
  150.  
  151. /* ------------------------------------------------------------------------- */
  152.  
  153. int    main(int argc, char **argv)
  154. {
  155. int        i, error = 0, rval;
  156.  
  157.     my_name = argv[0];
  158.     if(argc == 1){
  159.         printf("vmount mounted directories:\n");
  160.         print_all();
  161.     }else{
  162.         for(i=1;i<argc;i++){
  163.             error |= umount_dir(argv[i]);
  164.         }
  165.     }
  166.     rval = error ? 1 : 0;
  167.     return rval;
  168. }
  169.  
  170. /* ------------------------------------------------------------------------- */
  171.