home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / most-3.2 / part02 / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  11.4 KB  |  502 lines

  1. /*
  2.  * HISTORY
  3.  * {1}    19-Mar-91  Henk D. Davids <hdavids@mswe.dnet.ms.philips.nl>
  4.  *     History started. Added default input file name so you do not
  5.  *    have to specify name or type if you want it to be *.
  6.  *     Changes indicated by "-hdd" in comment.
  7.  * 
  8.  *  2.  4/4/91  John E. Davis
  9.  *      I added code to read the teminal size for unix systems-- at least it
  10.  *      works on a sun4 (BSD ?).  In addition I have also recently added file
  11.  *      deletion code for both unix and vms.
  12.  */
  13. #include "sysdep.h"
  14.  
  15.  
  16. /* 
  17.  *  
  18.  *  
  19.  *                          SHELL COMMANDS
  20.  *  
  21.  */
  22.   
  23. #ifdef VMS
  24.  
  25. /* these two from emacs source */  
  26. void define_logical_name (char *varname, char *string)
  27. {
  28.     struct dsc$descriptor_s strdsc =
  29.       {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
  30.     struct dsc$descriptor_s envdsc =
  31.       {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
  32.     struct dsc$descriptor_s lnmdsc =
  33.       {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
  34.  
  35.     LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
  36. }
  37.  
  38. void delete_logical_name (char *varname)
  39. {
  40.     struct dsc$descriptor_s envdsc =
  41.       {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
  42.     struct dsc$descriptor_s lnmdsc =
  43.       {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
  44.     
  45.     LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
  46. }
  47.  
  48.  
  49. int do_emacs_command()
  50. {
  51.     unsigned long pid;
  52.     char *pidstr;
  53.     
  54.     if((pidstr = getenv("EMACS_PID")) != NULL)
  55.       {
  56.       (void) sscanf(pidstr,"%X",&pid);
  57.       if (lib$attach(&pid) == SS$_NORMAL) /* we attach to emacs */
  58.             return(1);
  59.           else
  60.             return(0);
  61.           /*         printf("Can't attach to pid %X\n",pid); */
  62.       }
  63.     else return(0);
  64. }
  65.  
  66. unsigned long SHELL_PID = 0;  
  67.  
  68. /* returns 0 on success */
  69. int do_shell_command()
  70. {
  71.     /* here we try to attach to the parent otherwise just spawn a new one */
  72.     unsigned long parent_pid;
  73.     unsigned long status = 0;
  74.     char str[80];
  75.     
  76.     
  77.     parent_pid = getppid();
  78.     
  79.     if (parent_pid && parent_pid != 0xffffffff)  
  80.       /* we attach to parent */
  81.       status = lib$attach(&parent_pid);
  82.  
  83.     else if (SHELL_PID && SHELL_PID != 0xffffffff)
  84.       /* try to attach to previous shell */
  85.       status = lib$attach (&SHELL_PID);
  86.       
  87.     if (status != SS$_NORMAL)        /* others fail so spawn a new shell */
  88.       {
  89.           status = 0;
  90.       fputs("Spawning Subprocess...",stdout);
  91.           fflush(stdout);
  92.       lib$spawn(0,0,0,0,0,&SHELL_PID,&status);
  93.           /* if we attach back, status may come back unchanged */
  94.           if ((status != 0) && (status != SS$_NORMAL))
  95.             {
  96.                 sprintf(str,"Unable to spawn subprocess. Error = %X", status);
  97.                 message(str,1);
  98.                 return(0);
  99.             }
  100.       }
  101.     return(1);
  102. }
  103.  
  104.  
  105. #endif /* VMS */
  106.  
  107. /* 
  108.  *                            FILE IO
  109.  *  
  110.  */
  111.  
  112. #ifdef VMS
  113. int expand_file_name(char *file,char *expanded_file)
  114. {
  115.     unsigned long status;
  116.     static int context = 0;
  117.     static char inputname[255] = "";
  118.     $DESCRIPTOR(file_desc,inputname);
  119.     $DESCRIPTOR(default_dsc,"SYS$DISK:[]*.*;");
  120.     static struct dsc$descriptor_s  result = 
  121.         {0, DSC$K_DTYPE_T, DSC$K_CLASS_D, NULL};
  122.  
  123.     if (strcmp(inputname, file))
  124.       {
  125.       if (context)
  126.         {
  127.         lib$find_file_end(&context);
  128.         }
  129.       context = 0;
  130.       strcpy(inputname, file);
  131.       file_desc.dsc$w_length = strlen(inputname);
  132.       }
  133.     
  134.     if (RMS$_NORMAL == lib$find_file(&file_desc,&result,&context,
  135.                             &default_dsc,0,0,&0))
  136.       {
  137.       memcpy(expanded_file, result.dsc$a_pointer, result.dsc$w_length);
  138.       expanded_file[result.dsc$w_length] = '\0';
  139.           return (1);
  140.       }
  141.     else
  142.       {
  143.           expanded_file[0] = '\0';       /* so file comes back as zero width */
  144.           return(0);
  145.       }
  146. }
  147. #endif /* VMS */
  148.  
  149. /* 
  150.  *  
  151.  *  
  152.  *         Terminal IO
  153.  *  
  154.  */
  155.  
  156. #ifdef VMS
  157. /*
  158.  *      Exit Handler Control Block
  159.  */
  160. static struct argument_block
  161.     {
  162.     int forward_link;
  163.     int (*exit_routine)();
  164.     int arg_count;
  165.     int *status_address;
  166.     int exit_status;
  167.     } exit_block
  168.       = {
  169.         0,
  170.         NULL,
  171.         1,
  172.         &exit_block.exit_status,
  173.         0
  174.         };
  175. #endif
  176. void init_tty()
  177. {
  178. #ifdef VMS
  179.     $DESCRIPTOR ( Term, "SYS$ERROR");
  180.     if (sys$assign ( &Term, &TTY_CHANNEL_GLOBAL, 0, 0 )
  181.         != SS$_NORMAL)
  182.       {
  183.           fprintf(stderr,"Unable to assign input channel\n");
  184.           exit(0);
  185.       }
  186.     if (NULL == exit_block.exit_routine)
  187.     {
  188.     void reset_tty();
  189.  
  190.     exit_block.exit_routine = reset_tty;
  191.     SYS$DCLEXH(&exit_block);
  192.     }
  193. #else    
  194. #ifdef BSD
  195.     struct sgttyb  newtty;
  196.     struct tchars tc;
  197.     struct ltchars lc;
  198.  
  199.     ioctl(TTY_DESCR, TIOCGLTC,&OLDTTY_LC);
  200.     ioctl(TTY_DESCR, TIOCGETC,&OLDTTY_TC);
  201.     ioctl(TTY_DESCR, TIOCGETP, &OLDTTY);
  202.     newtty = OLDTTY;
  203.     newtty.sg_flags |= CBREAK;
  204.     newtty.sg_flags &= ~(ECHO | XTABS);
  205.     newtty.sg_erase = 0;
  206.     newtty.sg_kill = 0;
  207.     tc.t_intrc = 0;
  208.     tc.t_quitc = 0;
  209.     tc.t_eofc = 0;
  210.     tc.t_brkc = 0;
  211.     lc.t_suspc = 0;
  212.     lc.t_dsuspc = 0;
  213.     ioctl(TTY_DESCR, TIOCSETP, &newtty);
  214.     ioctl(TTY_DESCR, TIOCSLTC,&lc);
  215.     ioctl(TTY_DESCR, TIOCSETC,&tc);
  216. #else /* other unix */    
  217.     struct termio newtty;
  218.       
  219.     ioctl(TTY_DESCR, TCGETA, &OLDTTY);
  220.     ioctl(TTY_DESCR, TCGETA, &newtty);
  221.     newtty.c_iflag &= ~(ECHO);  
  222.     newtty.c_iflag &= ~(INLCR);  
  223.     newtty.c_iflag &= ~(ICRNL);  
  224.     newtty.c_lflag = 00000000; 
  225.     newtty.c_cc[VMIN] = 1; 
  226.     newtty.c_cc[VTIME] = 0;
  227.     newtty.c_cc[VEOF] = 1;          
  228.     ioctl(TTY_DESCR, TCSETA, &newtty);
  229.  
  230. #endif  /* other unix */
  231. #endif
  232.     fputs("\033=", stdout);  /* Enable the Application Keypad */
  233. }
  234.  
  235. sys_flush(int fd)
  236. {
  237. #ifdef BSD
  238.     ioctl(fd, TIOCFLUSH, (char *) NULL);
  239. #else
  240. #ifndef VMS    
  241.     ioctl(fd, TCFLSH, (char *) NULL);
  242. #endif    
  243. #endif    
  244. }
  245.  
  246. void reset_tty()
  247. {
  248.     fputs("\033=", stdout);  /* Enable the Numeric Keypad */
  249. #ifndef VMS
  250. #ifdef BSD
  251.     ioctl(TTY_DESCR, TIOCSETP, &OLDTTY);
  252.     ioctl(TTY_DESCR, TIOCSLTC, &OLDTTY_LC);
  253.     ioctl(TTY_DESCR, TIOCSETC, &OLDTTY_TC);
  254. #else        
  255.         ioctl(TTY_DESCR, TCSETA, &OLDTTY);
  256. #endif /* BSD */
  257. #endif /* not vms*/
  258. }
  259.  
  260. int INPUT_BUFFER_LEN = 0;
  261. char INPUT_BUFFER[80];
  262.  
  263. char sys_getkey()
  264. {
  265.     char c;
  266.     
  267. #ifndef VMS
  268.     if (read(TTY_DESCR, &c, 1) < 0)
  269.       {
  270.           fprintf(stderr,"getkey():  read failed.\n");
  271.           reset_tty();
  272.           exit(0);
  273.       }
  274.     
  275. #else
  276.     /* VMS */
  277.     /* see Guide to Programming VAX/VMS */
  278.     int status;
  279.     static int trmmsk [2] = { 0, 0 };
  280.     short iosb [4];
  281.     
  282.     status = sys$qiow ( 0, TTY_CHANNEL_GLOBAL,
  283.                        IO$_READVBLK + IO$M_NOECHO | IO$_TTYREADALL,
  284.                        iosb, 0, 0,
  285.                        &c, 1, 0, trmmsk, 0, 0 );
  286.  
  287. #endif  /* VMS */
  288.     
  289.     return(c); 
  290. }
  291.  
  292. char getkey()
  293. {
  294.     int i;
  295.     char ch;
  296.     if (!INPUT_BUFFER_LEN) return(sys_getkey());
  297.     ch = INPUT_BUFFER[0];
  298.     INPUT_BUFFER_LEN--;
  299.     for (i = 0; i < INPUT_BUFFER_LEN; i++)
  300.       {
  301.           INPUT_BUFFER[i] = INPUT_BUFFER[i + 1];
  302.       }
  303.     return(ch);
  304. }
  305.  
  306. void ungetkey(char ch)
  307. {
  308.     int i;
  309.     for (i = 0; i < INPUT_BUFFER_LEN; i++)
  310.       {
  311.           INPUT_BUFFER[i+1] = INPUT_BUFFER[i];
  312.       }
  313.     INPUT_BUFFER[0] = ch;
  314.     INPUT_BUFFER_LEN++;
  315. }
  316.  
  317.  
  318. /* 
  319.  *  
  320.  *      Misc Termial stuff  
  321.  *  
  322.  *  
  323.  */
  324.  
  325.  
  326. /*  This is to get the size of the terminal  */
  327. void get_term_dimensions(int *cols, int *rows)
  328. {
  329. #ifdef VMS
  330.     int status;
  331.     iosb iostatus;
  332.     $DESCRIPTOR(devnam, "SYS$ERROR");
  333.     struct
  334.     {
  335.     short row_buflen;
  336.     short row_itmcod;
  337.     int *row_bufadr;
  338.     short *row_retlen;
  339.     short col_buflen;
  340.     short col_itmcod;
  341.     int *col_bufadr;
  342.     short *col_retlen;
  343.     int listend;
  344.     } itmlst =
  345.     {
  346.     sizeof(*rows), DVI$_TT_PAGE, rows, 0,
  347.     sizeof(*cols), DVI$_DEVBUFSIZ, cols, 0,
  348.     0
  349.     };
  350.     
  351.     /* Get current terminal characteristics */
  352.     status = sys$getdviw(0,           /* Wait on event flag zero  */
  353.                          0,           /* Channel to input terminal  */
  354.                          &devnam,     /* device name */
  355.              &itmlst,      /* Item descriptor List */
  356.                          &iostatus,   /* Status after operation */
  357.                          0, 0,        /* No AST service   */
  358.                          0);          /* nullarg */
  359.     if (status&1)
  360.     status = iostatus.i_cond;
  361.     /* Jump out if bad status */
  362.     if ((status & 1) == 0)
  363.       exit(status);
  364. #else    /* this may need work on other unix-- works for sun4 */
  365.     struct winsize wind_struct;
  366.       
  367.     ioctl(2,TIOCGWINSZ,&wind_struct);
  368.     *cols = (int) wind_struct.ws_col;
  369.     *rows = (int) wind_struct.ws_row;
  370.     
  371. #endif /* VMS */
  372. }
  373.  
  374. /* returns 0 on failure, 1 on sucess */
  375. int sys_delete_file(char *filename)
  376. {
  377. #ifdef VMS
  378.     return (1 + delete(filename));   /* 0: sucess; -1 failure */
  379. #else  /* unix not ready yet */
  380.     return(1 + unlink(filename));
  381. #endif
  382. }
  383.  
  384.  
  385. /* This routine converts unix type names to vms names */
  386. #ifdef VMS
  387. int locate(char ch, char *string)
  388. {
  389.     int i;
  390.     char c;
  391.  
  392.     i = 0;
  393.     while (c = string[i++], (c != ch) && (c != '\0'));
  394.     if (c == ch) return(i); else return (0);
  395. }
  396.  
  397. char *unix2vms(char *file)
  398. {
  399.     int i,device,j,first,last;
  400.     static char vms_name[80];
  401.     char ch;
  402.  
  403.     if (locate('[',file)) return(file); /* vms_name syntax */
  404.     if (!locate('/',file)) return(file); /* vms_name syntax */
  405.  
  406.     /* search for the ':' which means a device is present */
  407.     device = locate(':',file);
  408.  
  409.     i = 0;
  410.     if (device)
  411.       {
  412.           while (ch = file[i], i < device) vms_name[i++] = ch;
  413.       }
  414.     j = i;
  415.     
  416.     /* go from the  end looking for a '/' and mark it */
  417.     i = strlen(file) - 1;
  418.     while(ch = file[i], ch != '/' && i-- >= 0);
  419.     if (ch == '/')
  420.       {
  421.           file[i] = ']';
  422.           last = 0;
  423.       }
  424.     else last = 1;
  425.  
  426.     i = j;
  427.     vms_name[j++] = '[';
  428.     vms_name[j++] = '.';
  429.     first = 0;
  430.     while(ch = file[i++], ch != '\0')
  431.       {
  432.           switch (ch)
  433.             {
  434.               case '.':
  435.                 if (last) vms_name[j++] = '.';
  436.                 if (last) break;
  437.                 ch = file[i++];
  438.                 if (ch == '.')
  439.                   {
  440.                       if (!first) j--;  /* overwrite the dot */
  441.                       vms_name[j++] = '-';
  442.                   }
  443.                 else if (ch == '/'); /*  './' combinations-- do nothing */
  444.                 else if (ch == ']')
  445.                   {
  446.                       last = 1;
  447.                       if (vms_name[j-1] == '.') j--;
  448.                       vms_name[j++] = ']';
  449.                   }
  450.                 
  451.                 else vms_name[j++] = '.';
  452.                 break;
  453.               case '/':
  454.                 if (first)
  455.                   {
  456.                       vms_name[j++] = '.';
  457.                   }
  458.                 else
  459.                   {
  460.                       first = 1;
  461.                       /* if '/' is first char or follows a colon do nothing */
  462.                       if ((i!=1) && (file[i-2] != ':'))
  463.                         {
  464.                             vms_name[j++] = '.';
  465.                         }
  466.                       else j--; /* overwrite the '.' following '[' */
  467.                   }
  468.                 break;
  469.               case ']':
  470.                 last = 1;
  471.                 if (vms_name[j-1] == '.') j--;
  472.                 vms_name[j++] = ']';
  473.                 break;
  474.               default:
  475.                 vms_name[j++] = ch;
  476.             }
  477.       }
  478.     return (vms_name);
  479. }
  480.  
  481. /*
  482. main(int argc, char **argv)
  483. {
  484.     puts(unix2vms(argv[1]));
  485. }
  486. */     
  487.  
  488. #endif /* VMS */
  489.  
  490. #include <time.h>
  491.  
  492. char *get_time()
  493.     time_t clock;
  494.     char *the_time;
  495.  
  496.     clock = time((long *) 0);
  497.     the_time = ctime(&clock); /* returns the form Sun Sep 16 01:03:52 1985\n\0 */
  498.     the_time[24] = '\0';
  499.     return(the_time);
  500. }
  501.