home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / mtools-3.000 / mtools-3 / mtools-3.0 / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-08  |  5.8 KB  |  336 lines

  1. /*
  2.  * Miscellaneous routines.
  3.  */
  4.  
  5. #include "sysincludes.h"
  6. #include "msdos.h"
  7. #include "stream.h"
  8. #include "vfat.h"
  9. #include "mtools.h"
  10.  
  11. char *get_homedir(void)
  12. {
  13.     struct passwd *pw;
  14.     int uid;
  15.     char *homedir;
  16.     char *username;
  17.     
  18.     homedir = getenv ("HOME");    
  19.     /* 
  20.      * first we call getlogin. 
  21.      * There might be several accounts sharing one uid 
  22.      */
  23.     if ( homedir )
  24.         return homedir;
  25.     
  26.     pw = 0;
  27.     
  28.     username = getenv("LOGNAME");
  29.     if ( !username )
  30.         username = getlogin();
  31.     if ( username )
  32.         pw = getpwnam( username);
  33.   
  34.     if ( pw == 0 ){
  35.         /* if we can't getlogin, look up the pwent by uid */
  36.         uid = geteuid();
  37.         pw = getpwuid(uid);
  38.     }
  39.     
  40.     /* we might still get no entry */
  41.     if ( pw )
  42.         return pw->pw_dir;
  43.     return 0;
  44. }
  45.  
  46. static FILE *tty=NULL;
  47. static int notty=0;    
  48. static int ttyfd=-1;
  49. static int tty_mode = -1; /* 1 for raw, 0 for cooked, -1 for initial */
  50. static int need_tty_reset = 0;
  51.  
  52.  
  53. #ifdef TCSANOW
  54.  
  55. /* we have tcsetattr & tcgetattr. Good */
  56. #define stty(a,b)        (void)tcsetattr(a,TCSANOW,b)
  57. #define gtty(a,b)        (void)tcgetattr(a,b)
  58. #ifdef TCIFLUSH
  59. #define discard_input(a) tcflush(a,TCIFLUSH)
  60. #else
  61. #define discard_input(a) /**/
  62. #endif
  63.  
  64. #else /* TCSANOW */
  65.  
  66. #ifndef TCSETS
  67. #define TCSETS TCSETA
  68. #define TCGETS TCGETA
  69. #define termios termio
  70. #endif
  71.  
  72. #define stty(a,b) (void)ioctl(a,TCSETS,(char *)b)
  73. #define gtty(a,b) (void)ioctl(a,TCGETS,(char *)b)
  74.  
  75. #ifdef TCIFLUSH
  76. #define discard_input(a) (void)ioctl(a,TCFLSH,TCIFLUSH)
  77. #else
  78. #define discard_input(a) /**/
  79. #endif
  80.  
  81. #endif /* TCSANOW */
  82.  
  83. #define restore_tty(a) stty(STDIN,a)
  84.  
  85.  
  86. #define SHFAIL    1
  87. #define STDIN ttyfd
  88. #define FAIL (-1)
  89. #define DONE 0
  90. static struct termios in_orig;
  91.  
  92. /*--------------- Signal Handler routines -------------*/
  93.  
  94. static void tty_time_out(void)
  95. {
  96.     int exit_code;
  97.     signal(SIGALRM, SIG_IGN);
  98.     if(tty && need_tty_reset)
  99.         restore_tty (&in_orig);    
  100. #if future
  101.     if (fail_on_timeout)
  102.         exit_code=SHFAIL;
  103.     else {
  104.         if (default_choice && mode_defined) {
  105.             if (yes_no) {
  106.                 if ('Y' == default_choice)
  107.                     exit_code=0;
  108.                 else
  109.                     exit_code=1;
  110.             } else
  111.                 exit_code=default_choice-minc+1;
  112.         } else
  113.             exit_code=DONE;
  114.     }
  115. #else
  116.     exit_code = DONE;
  117. #endif
  118.     exit(exit_code);
  119. }
  120.  
  121. void cleanup_and_exit(int code)
  122.     if(tty && need_tty_reset) {
  123.         restore_tty (&in_orig);
  124.         signal (SIGHUP, SIG_IGN);
  125.         signal (SIGINT, SIG_IGN);
  126.         signal (SIGTERM, SIG_IGN);
  127.         signal (SIGALRM, SIG_IGN);
  128.     }
  129.     exit(code);
  130. }
  131.  
  132. static void clean_up_and_fail(void)
  133. {
  134.     cleanup_and_exit(SHFAIL);
  135. }
  136.  
  137. static void set_raw_tty(int mode)
  138. {
  139.     struct termios in_raw;
  140.  
  141.     if(mode != tty_mode && mode != -1) {
  142.         /* Determine existing TTY settings */
  143.         gtty (STDIN, &in_orig);
  144.         need_tty_reset = 1;
  145.  
  146.         /*------ Restore original TTY settings on exit --------*/
  147.         signal (SIGHUP, (SIG_CAST)clean_up_and_fail);
  148.         signal (SIGINT, (SIG_CAST)clean_up_and_fail);
  149.         signal (SIGTERM, (SIG_CAST)clean_up_and_fail);
  150.         signal (SIGALRM, (SIG_CAST)tty_time_out);
  151.     
  152.         /* Change STDIN settings to raw */
  153.  
  154.         gtty (STDIN, &in_raw);
  155.         if(mode) {
  156.             in_raw.c_lflag &= ~ICANON;
  157.             in_raw.c_cc[VMIN]=1;
  158.             in_raw.c_cc[VTIME]=0;
  159.             stty (STDIN, &in_raw);
  160.         } else {
  161.             in_raw.c_lflag |= ICANON;
  162.             stty (STDIN, &in_raw);
  163.         }
  164.         tty_mode = mode;
  165.         discard_input(STDIN);
  166.     }
  167. }
  168.  
  169. FILE *opentty(int mode)
  170. {
  171.     if(notty)
  172.         return NULL;
  173.  
  174.     if (tty == NULL) {
  175.         ttyfd = open("/dev/tty", O_RDONLY);
  176.         if(ttyfd >= 0) {
  177.             tty = fdopen(ttyfd, "r");
  178.         }
  179.     }
  180.  
  181.     if  (tty == NULL){
  182.         if ( !isatty(0) ){
  183.             notty = 1;
  184.             return NULL;
  185.         }
  186.         ttyfd = 0;
  187.         tty = stdin;
  188.     }
  189.  
  190.     set_raw_tty(mode);
  191.     return tty;
  192. }
  193.  
  194. int ask_confirmation(char *format, char *p1, char *p2)
  195. {
  196.     char ans[10];
  197.  
  198.     if(!opentty(-1))
  199.         return 0;
  200.  
  201.     while (1) {
  202.         fprintf(stderr, format, p1, p2);
  203.         fflush(stderr);
  204.         fflush(opentty(-1));
  205.         if (mtools_raw_tty) {
  206.             ans[0] = fgetc(opentty(1));
  207.             fputs("\n", stderr);
  208.         } else {
  209.             fgets(ans,9, opentty(0));
  210.         }
  211.         if (ans[0] == 'y' || ans[0] == 'Y')
  212.             return 0;
  213.         if (ans[0] == 'n' || ans[0] == 'N')
  214.             return -1;
  215.     }
  216. }
  217.  
  218.  
  219. FILE *open_mcwd(char *mode)
  220. {
  221.     struct stat sbuf;
  222.     char file[EXPAND_BUF];
  223.     long now;
  224.     char *mcwd_path;
  225.     char *homedir;
  226.  
  227.     mcwd_path = getenv("MCWD");
  228.     if (mcwd_path == NULL || *mcwd_path == '\0'){
  229.         homedir= get_homedir();
  230.         if ( homedir ){
  231.             strncpy(file, homedir, MAXPATHLEN);
  232.             file[MAXPATHLEN]='\0';
  233.             strcat( file, "/.mcwd");
  234.         } else
  235.             strcpy(file,"/tmp/.mcwd");
  236.     } else
  237.         expand(mcwd_path,file);
  238.  
  239.     if (*mode == 'r'){
  240.         if (stat(file, &sbuf) < 0)
  241.             return NULL;
  242.         /*
  243.          * Ignore the info, if the file is more than 6 hours old
  244.          */
  245.         time(&now);
  246.         if (now - sbuf.st_mtime > 6 * 60 * 60) {
  247.             fprintf(stderr,
  248.                 "Warning: \"%s\" is out of date, removing it\n",
  249.                 file);
  250.             unlink(file);
  251.             return NULL;
  252.         }
  253.     }
  254.     
  255.     return  fopen(file, mode);
  256. }
  257.     
  258.  
  259. /* Fix the info in the MCWD file to be a proper directory name.
  260.  * Always has a leading separator.  Never has a trailing separator
  261.  * (unless it is the path itself).  */
  262.  
  263. char *fix_mcwd(char *ans)
  264. {
  265.     FILE *fp;
  266.     char *s;
  267.     char buf[BUFSIZ];
  268.  
  269.     fp = open_mcwd("r");
  270.     if(!fp){
  271.         strcpy(ans, "A:/");
  272.         return ans;
  273.     }
  274.  
  275.     if (!fgets(buf, BUFSIZ, fp))
  276.         return("A:/");
  277.  
  278.     buf[strlen(buf) -1] = '\0';
  279.     fclose(fp);
  280.                     /* drive letter present? */
  281.     s = buf;
  282.     if (buf[0] && buf[1] == ':') {
  283.         strncpy(ans, buf, 2);
  284.         ans[2] = '\0';
  285.         s = &buf[2];
  286.     } else 
  287.         strcpy(ans, "A:");
  288.                     /* add a leading separator */
  289.     if (*s != '/' && *s != '\\') {
  290.         strcat(ans, "/");
  291.         strcat(ans, s);
  292.     } else
  293.         strcat(ans, s);
  294.                     /* translate to upper case */
  295.     for (s = ans; *s; ++s) {
  296.         *s = toupper(*s);
  297.         if (*s == '\\')
  298.             *s = '/';
  299.     }
  300.                     /* if only drive, colon, & separator */
  301.     if (strlen(ans) == 3)
  302.         return(ans);
  303.                     /* zap the trailing separator */
  304.     if (*--s == '/')
  305.         *s = '\0';
  306.     return ans;
  307. }
  308.  
  309. int maximize(int *target, int max)
  310. {
  311.     if (*target > max)
  312.         *target = max;
  313.     return *target;
  314. }
  315.  
  316. int minimize(int *target, int min)
  317. {
  318.     if (*target < min)
  319.         *target = min;
  320.     return *target;
  321. }
  322.  
  323.  
  324. void *safe_malloc(size_t size)
  325. {
  326.     void *p;
  327.  
  328.     p = malloc(size);
  329.     if(!p){
  330.         fprintf(stderr,"Out of memory error\n");
  331.         exit(1);
  332.     }
  333.     return p;
  334. }
  335.