home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / cwish / part01 / commandline.c next >
Encoding:
C/C++ Source or Header  |  1993-09-22  |  18.5 KB  |  522 lines

  1. /*---------------------------------------------------------------------------*
  2.  *
  3.  *                  wish - windowing user friendly shell
  4.  *                 --------------------------------------
  5.  *
  6.  *              (c) Copyright Hellmuth Michaelis 1989 - 1993
  7.  *
  8.  *                  Eggerstedtstr. 28
  9.  *                  22765 Hamburg
  10.  *                  Germany
  11.  *
  12.  *                  Tel:    +49 / 40 / 384298    (private)
  13.  *                  Tel:    +49 / 40 / 55903-170 (at work)
  14.  *                  e-mail: hm@hcshh.hcs.de
  15.  *
  16.  *           All rights are reserved except as explicitly granted
  17.  *                  by written permission of the author.
  18.  *
  19.  *             See the file COPYING, distributed with wish, for
  20.  *                  restriction and warranty information
  21.  *
  22.  *---------------------------------------------------------------------------*
  23.  *
  24.  *      last edit-date: [Mon Aug 30 12:27:37 1993]
  25.  *
  26.  *      -hm     debugging "more" output
  27.  *      -hm     separate sys-call function exec_command
  28.  *      -hm     time suspend/resume
  29.  *      -hm     nochng flag introduced
  30.  *      -hm     current dir preserve when cd ..
  31.  *      -hm     compress / gzip support
  32.  *      -hm     tar support
  33.  *      -hm     no space on echo to first cmdline pos
  34.  *      -hm     fixed no space bug ....
  35.  *      -hm     curdir debugging
  36.  *      -hm     housekeeping
  37.  *      -hm     cd bugfix, cdmount did not do what it should
  38.  *      -hm     new routine ending to support multiple extensions
  39.  *      -hm     cd with wildcards
  40.  *      -hm     cdrom special processing for filenames containing ';'
  41.  *
  42.  *----------------------------------------------------------------------------*/ 
  43.  
  44. #include "wish.h"               /* local includes */
  45.  
  46. static int waitcr = 0;          /* do not wait for cr */
  47. static int reread = 0;          /* reread current dir */
  48. static int nochng = 0;          /* nothing has changed */
  49. static int preserve = PRES_NO;  /* preserve highlighted position */
  50. static char curdirb[MAXPATHLEN+1];
  51. static char *curdir = curdirb;  /* current dir to preserve if cd .. */
  52.  
  53. static char *str_nxtw(char *, int); /* returns a pointer to the next word in string */
  54. static char *ending(char *filename);
  55. static char *adjustfn(register char *name);
  56.  
  57. /*---------------------------------------------------------------------------*
  58.  *      echo the current highlighted filename onto the commandline
  59.  *---------------------------------------------------------------------------*/
  60. void name_echo(void)
  61. {
  62.         char *ptr;              /* temp ptr */
  63.  
  64.         ptr = &(cur_file->onam[1]);     /* ptr = current filename */
  65.                                         /* check for delimiter */
  66.         
  67.         if( (!(cr_on_files())) && (cbuff[curcol()-1] != SPACE) )
  68.                 cmdline(SPACE);         /* if none, insert one */
  69.                 
  70.         ptr = adjustfn(ptr);
  71.  
  72.         while((*ptr) && ((cmdline(*ptr++)) == GOOD))
  73.                 ;
  74. }
  75.  
  76. /*---------------------------------------------------------------------------*
  77.  *      returns a pointer to the next word in string
  78.  *---------------------------------------------------------------------------*/
  79. static char *str_nxtw(char *str, int frst)
  80. {
  81.         char *r;
  82.         
  83.         if((str == NULL) || (*str == '\0'))
  84.                 return(NULL);
  85.  
  86.         r = str;
  87.         
  88.         if(frst)
  89.         {
  90.                 while(*r == SPACE)      /* while leading delimiters */
  91.                         r++;
  92.                 if(*r != '\0')
  93.                         return(r);      /* first non-space char */
  94.                 else
  95.                         return(NULL);
  96.         }
  97.         else
  98.         {
  99.                 while((*r != SPACE) && (*r != '\0')) /* find space */
  100.                         r++;
  101.                 if(*r == '\0')          /* test for end of string */
  102.                         return(NULL);
  103.                 while(*r == SPACE)      /* while there are delimiters */
  104.                         r++;
  105.                 if(*r != '\0')
  106.                         return(r);      /* first non-space char */
  107.                 else
  108.                         return(NULL);   /* end of string */
  109.         }
  110. }
  111.  
  112. /*---------------------------------------------------------------------------*
  113.  *      expand the selection character onto the commandline
  114.  *---------------------------------------------------------------------------*/
  115. void expsel(char *p)
  116. {
  117.         char rest[512];         /* save buffer */
  118.         struct onefile *info;   /* our file struct ptr */
  119.         int i;                  /* free space counter in cbuff */
  120.         register char *fnp;     /* for filename conversion */
  121.  
  122.         strcpy(rest,p+1);       /* save right half of cbuff after EXPSEL-char */
  123.  
  124.         if(*(p-1) != SPACE)     /* check for delimiter present */
  125.         {
  126.                 *p = SPACE;
  127.                 p++;
  128.         }
  129.         
  130.         i = (p - cbuff) + strlen(rest); /* count of already occupied chars */
  131.         
  132.         info = first;           /* first in list */
  133.  
  134.         *p = '\0';              /* terminate left half of cbuff */
  135.         
  136.         while(info)             /* scan through dir - list */
  137.         {
  138.                 if(info->tag)   /* search for tagged files */
  139.                 {
  140.                         fnp = adjustfn(&(info->onam[1]));
  141.                         
  142.                         if(((strlen(fnp))+1) < (HISLNLEN - i))
  143.                         {
  144.                                 /* we have enough space  */
  145.  
  146.                                 i += (strlen(fnp)+1);
  147.                                 strcat(cbuff, fnp);
  148.                                 strcat(cbuff," ");
  149.                         }
  150.                 }
  151.                 info = info->next;      /* next entry */
  152.         }
  153.         strcat(cbuff,rest);     /* copy saved right half to generated part */
  154. }
  155.  
  156. /*---------------------------------------------------------------------------*
  157.  *      user has typed a <CR>
  158.  *---------------------------------------------------------------------------*/
  159. void handlecr(void)
  160. {
  161.         nochng = 0;             /* anything may change on screen */
  162.         preserve = PRES_NORM;   /* nothing to preserve */
  163.         
  164.         if(cr_on_files())       /* nothing on commandline, process high- */
  165.         {                       /*  lighted filename field */
  166.                 h_files();      /* cr on a filename */
  167.         }
  168.         else    /* something in commandlinebuffer */
  169.         {
  170.                 h_line();       /* commandline */
  171.         }
  172.  
  173.         if(waitcr && opt_return)        /* wait for <cr> being hit */
  174.         {
  175.                 move(LINES-1, 0);       /* last line */
  176.                 clrtoeol();             /* clear it */
  177.                 move(LINES-1, 0);       /* last line */
  178.                 attrset(A_REVERSE);             /* highlight on */
  179.                 addstr("Press any key to continue ...");
  180.                 attroff(A_REVERSE);             /* highlight on */              
  181.                 refresh();
  182.                 getch();
  183.                 move(LINES-1, 0);       /* last line */
  184.                 clrtoeol();             /* clear it */
  185.                 touchwin(stdscr);
  186.                 wnoutrefresh(stdscr);
  187.         }
  188.         header();       /* new header */
  189.         dis_hist();     /* display current history entry */
  190.  
  191.         if(reread)      /* directory has to be re-read */
  192.         {
  193.                 free_list();            /* free malloc'ed buffers */
  194.                 init_files(preserve, curdir);   /* yes, read current dir */
  195.         }
  196.         else
  197.         {
  198.                 if(!nochng)
  199.                         fresh_files();  /* just refresh window */
  200.         }
  201.         resume_time();          /* restart time display update */
  202.         if(!nochng)
  203.         {
  204.                 attribs(1);             /* new attributes */
  205.                 init_flabels();         /* fk-labels onto screen */
  206.                 update_all();           /* update all windows */
  207.         }
  208.         else
  209.         {
  210.                 wrefresh(cmnd_w);
  211.         }
  212. }
  213.  
  214. /*---------------------------------------------------------------------------*
  215.  *      user has typed <CR> and something is on commandline
  216.  *---------------------------------------------------------------------------*/
  217. void h_line(void)
  218. {
  219.         char *cptr = cbuff+3;   /* ptr to start of line after prompt */
  220.         char *cp;               /* command ptr */
  221.         char *ap;               /* argument ptr */
  222.         char *ep;               /* expansion char ptr */
  223.  
  224.         if((cp = str_nxtw(cptr,1)) == NULL)     /* just spaces on commandline ? */
  225.         {       
  226.                 nochng = 1;
  227.                 errno = 0;                      /* yes ... */
  228.                 error("commandline empty ... ");
  229.                 waitcr = 0;
  230.                 reread = 0;
  231.         }
  232.         else if( (*cp == 'c') && (*(cp+1) == 'd') &&
  233.                  ( (*(cp+2) == ' ') || (*(cp+2) == '\t') || (*(cp+2) == '\0') ) )
  234.         {
  235.                 int ret;
  236.                 if((ap = str_nxtw(cp, 0)) == NULL)
  237.                 {
  238.                         ret = chdir(envhome);   /* cd to home */
  239.                 }
  240.                 else
  241.                 {
  242.                         char *ptr;
  243.  
  244.                         if((ptr = (char *)index(ap, '.')) != NULL)
  245.                         {
  246.                                 if(!(strncmp(ptr, "..", 2)))
  247.                                 {
  248.                                         if(getcwd(curdir, MAXPATHLEN) == NULL)
  249.                                                 *curdir = '\0';
  250.                                         preserve = PRES_DD;
  251.                                 }
  252.                         }
  253.                         ret = cd(ap);   /* cd to <dir> */
  254.                 }
  255.  
  256.                 if(ret == -1)
  257.                 {
  258.                         nochng = 1;
  259.                         error("changing directory failed - chdir() error");
  260.                         waitcr = 0;
  261.                         reread = 0;
  262.                 }
  263.                 else
  264.                 {
  265.                         waitcr = 0;
  266.                         reread = 1;
  267.                 }                       
  268.         }
  269.         else
  270.         {
  271.                 if((ep = strchr((cbuff+3),EXPSEL)) != NULL)             
  272.                         expsel(ep);             /* expand selection char */
  273.  
  274.                 exec_command(cbuff+3);
  275.  
  276.                 waitcr = 1;             /* wait for <cr> */
  277.                 reread = 1;             /* reread current dir */
  278.         }
  279.         save_line();                    /* save commandline to history */       
  280. }
  281.         
  282. /*---------------------------------------------------------------------------*
  283.  *      user has typed <CR> and commandline is empty
  284.  *---------------------------------------------------------------------------*/
  285. void h_files(void)
  286. {               
  287.         preserve = PRES_NORM;
  288.         
  289.         if(cur_file->oprm[0] == 'd')    /* directories */
  290.         {
  291.                 preserve = PRES_DD;
  292.  
  293.                 if(getcwd(curdir, MAXPATHLEN) == NULL)
  294.                         *curdir = '\0';
  295.  
  296.                 if((chdir(&(cur_file->onam[1]))) == -1)
  297.                 {
  298.                         nochng = 1;
  299.                         error("changing directory to current selection failed - chdir() error");
  300.                         reread = 0;     /* no need to re-read */
  301.                 }
  302.                 else
  303.                 {
  304.                         reread = 1;     /* (re-) read (new) dir */
  305.                 }
  306.  
  307.                 waitcr = 0;             /* don't wait for <CR> */
  308.         }
  309.  
  310.         /* executables */
  311.  
  312.         else if((cur_file->oprm[3] == 'x') ||
  313.                 (cur_file->oprm[6] == 'x') ||
  314.                 (cur_file->oprm[9] == 'x'))
  315.         {
  316.                 sprintf(cbuff, "%s/%s", cur_path, &(cur_file->onam[1]));
  317.  
  318.                 exec_command(cbuff);            /* shell-call */
  319.  
  320.                 waitcr = 1;
  321.                 reread = 1;
  322.         }
  323.  
  324.         /* data files */
  325.         else if((cur_file->oprm[1] == 'r') ||
  326.                 (cur_file->oprm[4] == 'r') ||
  327.                 (cur_file->oprm[7] == 'r'))                     
  328.         {
  329.                 FILE *pfp;
  330.                 char *pp;
  331.                 char *fnp;
  332.  
  333.                 fnp = adjustfn(&(cur_file->onam[1]));
  334.  
  335.                 sprintf(cbuff, "cat %s/%s", cur_path, fnp);
  336.                 
  337.                 if((pp = ending(fnp)) != NULL)
  338.                         strcat(cbuff, pp);
  339.  
  340.                 strcat(cbuff,"|");              /* pipe to pager */     
  341.                 strcat(cbuff, opt_more);        /* pager */
  342.                 
  343.                 suspend_time();         /* stop updating time */
  344.                 fini_flabels();         /* remove user labels */
  345.                 move(0, 0);             /* first line */
  346.                 touchwin(stdscr);       /* force */
  347.                 clear();                /* clear it */
  348.                 refresh();              /* update screen */
  349.                 savetty();              /* save tty-modes for resetty() */
  350.                 reset_shell_mode();     /* set tty to pre-curses values */
  351.                 
  352.                 if((pfp = popen(cbuff, "w")) == NULL)   /* exec */
  353.                         error("cannot open pipe to PAGER");
  354.                 else
  355.                 {
  356.                         if(pclose(pfp) == -1)
  357.                                 error("PAGER pclose error");
  358.                 }
  359.  
  360.                 resetty();              /* restore modes to curses operation */
  361.  
  362.                 reset_prog_mode();      /* set to curses values */
  363.                 
  364. #ifdef CURSESBUG
  365.                 putp(keypad_xmit);      /* hp curses bug .. */
  366. #endif
  367.  
  368.                 touchwin(cmnd_w);
  369.                 touchwin(fst_w);
  370.                 touchwin(file_w);
  371.                 if(opt_attrib)
  372.                         touchwin(attr_w);
  373.                 if(opt_labels)
  374.                         touchwin(flbl_w);
  375.         
  376.                 resume_time();          /* restart updating time */
  377.                 waitcr = 0;             /* don't wait for <CR> */
  378.                 reread = 0;             /* reread dir */
  379.         }
  380.  
  381.         /* OOPS, whats this ?? */
  382.         else
  383.         {
  384.                 errno = 0;              /* no errno display */
  385.                 error("no exec/read permission found ....");
  386.                 flash();                /* no no .. */
  387.                 waitcr = 0;             /* don't wait for <CR> */
  388.                 reread = 0;             /* don't reread dir !!! */
  389.         }
  390. }
  391.  
  392. /*---------------------------------------------------------------------------*
  393.  *      what to do with the file depending on ending
  394.  *---------------------------------------------------------------------------*/
  395. static char *ending(char *filename)
  396. {
  397.         int i;
  398.         char *p;
  399.  
  400.         static char *etab[][2] = {
  401.                 {".tar.Z",      "|compress -dfc|tar tvf -"},
  402.                 {".tar.z",      "|gzip -cdf|tar tvf -"},
  403.                 {".tar.gz",     "|gzip -cdf|tar tvf -"},
  404.                 {".tar",        "|tar tvf -"},
  405.                 {".Z",          "|compress -dfc"},
  406.                 {".z",          "|gzip -cdf"},
  407.                 {".gz",         "|gzip -cdf"},
  408.                 {NULL, NULL}
  409.         };
  410.  
  411.         /* see if filename contains a known extension and return the    */
  412.         /* commandline string to decode that file                       */
  413.  
  414.         for(i = 0; etab[i][0] != NULL; i++)
  415.         {
  416.                 if( ((p = strstr(filename, etab[i][0])) != NULL) &&
  417.                     (strlen(p) == strlen(etab[i][0])) )
  418.                         return(etab[i][1]);
  419.         }
  420.         return(NULL);
  421. }
  422.  
  423. /*---------------------------------------------------------------------------*
  424.  *      edit the current file
  425.  *---------------------------------------------------------------------------*/
  426. void edit_current(void)
  427. {
  428.         char *fnp;
  429.  
  430.         if(cur_file->oprm[0] == 'd')    /* directories */
  431.                 return;
  432.  
  433.         fnp = adjustfn(&(cur_file->onam[1]));
  434.         
  435.         sprintf(cbuff,"%s %s/%s", opt_edit, cur_path, fnp);
  436.  
  437.         exec_command(cbuff);            /* shell-call */
  438.  
  439.         header();               /* new header */
  440.         dis_hist();             /* display current history */
  441.         fresh_files();          /* display files */
  442.         attribs(1);             /* new attributes */
  443.         init_flabels();         /* fk-labels onto screen */
  444.         update_all();
  445.         resume_time();          /* restart time display update */       
  446. }
  447.  
  448. /*---------------------------------------------------------------------------*
  449.  *      close current directory
  450.  *---------------------------------------------------------------------------*/
  451. void close_cdir(void)
  452. {
  453.         if(getcwd(curdir, MAXPATHLEN) == NULL)
  454.                 *curdir = '\0';
  455.         
  456.         if((chdir("..")) == -1)
  457.         {
  458.                 error("changing directory to '..' dir failed - chdir() error");
  459.                 return;
  460.         }
  461.         else
  462.         {
  463.                 header();               /* new header */
  464.                 free_list();            /* free malloc'ed buffers */
  465.                 init_files(PRES_DD, curdir);    /* yes, read current dir */
  466.                 attribs(1);             /* new attributes */
  467.                 init_flabels();         /* fk-labels onto screen */
  468.         }
  469.         update_all();
  470. }
  471.  
  472. /*---------------------------------------------------------------------------*
  473.  *      execute a command/program
  474.  *---------------------------------------------------------------------------*/
  475. void exec_command(char *cline)
  476. {
  477.         suspend_time();         /* no time display update */
  478.         fini_flabels();         /* remove user labels */
  479.         move(0, 0);             /* last line */
  480.         touchwin(stdscr);       /* force */
  481.         clear();                /* clear it */
  482.         refresh();              
  483.         savetty();              /* save tty-modes for resetty() */
  484.         reset_shell_mode();     /* set to pre-curses values */
  485.         system(cline);          /* shell-call */
  486.         resetty();              /* restore modes to curses operation */
  487.         reset_prog_mode();      /* set to curses values */
  488.  
  489. #ifdef CURSESBUG
  490.         putp(keypad_xmit);      /* hp curses bug .. */
  491. #endif
  492.  
  493.         touchwin(cmnd_w);
  494.         touchwin(fst_w);
  495.         touchwin(file_w);
  496.         if(opt_attrib)
  497.                 touchwin(attr_w);
  498.         if(opt_labels)
  499.                 touchwin(flbl_w);
  500. }
  501.  
  502. /*---------------------------------------------------------------------------*
  503.  *      adjust filename (cdrom, others ?)
  504.  *---------------------------------------------------------------------------*/
  505. static char *adjustfn(char *name)
  506. {
  507.     static char buffer[MAXPATHLEN];
  508.     register char *bp = buffer;
  509.     register char *sp = name;
  510.     
  511.     while(*sp)
  512.     {
  513.         if(iscdfs && (*sp == ';'))
  514.             *bp++ = '\\';
  515.         *bp++ = *sp++;
  516.     }
  517.     *bp = '\0';
  518.     return((char *)buffer);
  519. }
  520.     
  521. /*---------------------------------- EOF -------------------------------------*/
  522.