home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / cwish / part02 / wish.c < prev   
Encoding:
C/C++ Source or Header  |  1993-09-22  |  14.1 KB  |  612 lines

  1. /*---------------------------------------------------------------------------*
  2.  *
  3.  *                  wish - windowing user friendly shell
  4.  *                  ------------------------------------
  5.  *
  6.  *               Copyright (c) 1988-1993 Hellmuth Michaelis
  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.  *                          --------oOo--------
  17.  *
  18.  *   This program is free software; you can redistribute it and/or modify
  19.  *   it under the terms of the GNU General Public License as published by
  20.  *   the Free Software Foundation; either version 2 of the License, or
  21.  *   (at your option) any later version.
  22.  *
  23.  *   This program is distributed in the hope that it will be useful,
  24.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26.  *   GNU General Public License for more details.
  27.  *
  28.  *   You should have received a copy of the GNU General Public License
  29.  *   along with this program; if not, write to the Free Software
  30.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  31.  *
  32.  *---------------------------------------------------------------------------*
  33.  *
  34.  *    Last Edit-Date: [Mon Aug 30 19:59:18 1993]
  35.  *
  36.  *    -hm    converting to curses and multiwindows
  37.  *    -hm    general cleanup ....
  38.  *    -hm    adding a close-current-dir function and fkey
  39.  *    -hm    adding history to command line
  40.  *    -hm    default display attribs on
  41.  *    -hm    changing coomandline control to emacs-commands
  42.  *    -hm    vt220 support, housekeeping
  43.  *    -hm    show time in header
  44.  *    -hm    try to preserve current position after command
  45.  *    -hm    backspace char from termio struct
  46.  *    -hm    porting to 386BSD
  47.  *    -hm    show links flag
  48.  *    -hm    config file processing "$HOME/.wishrc"
  49.  *    -hm    add / subtract option processing
  50.  *    -hm    exit() -> fatal() changed
  51.  *    -hm    hpterm / config menu
  52.  *    -hm    fixed delete character bug
  53.  *    -hm    fkey label structures
  54.  *    -hm    ESC,ESC filename completition
  55.  *    -hm    GNU copyleft
  56.  *
  57.  *----------------------------------------------------------------------------*/
  58.  
  59. #define MAIN            /* declare variables into this file */
  60.  
  61. #include "wish.h"        /* everything we want */
  62. #include "control.h"        /* control-characters */
  63.  
  64. /*---------------------------------------------------------------------------*
  65.  *    main loop
  66.  *---------------------------------------------------------------------------*/
  67. int main (int argc, char *argv[])
  68. {
  69.     char c;            /* just for argument processing */    
  70.     int i;            /* gp int */
  71.     int kchar;        /* character from keyboard */
  72.     int optmode;        /* add (1) or subtract (0) option mode */    
  73.     errorflag = 0;        /* no error yet */
  74.  
  75.     /* first - set up defaults from environment */
  76.  
  77.     if((envhome = getenv("HOME")) == NULL)
  78.     {
  79.         fprintf(stderr, "\n Environment variable \"HOME\" not set!\n");
  80.         exit(1);
  81.     }
  82.  
  83.     if((envmore = getenv("PAGER")) == NULL)
  84.     {
  85.         envmore = "more";    /* default pager for file display */
  86.     }
  87.  
  88.     if((envedit = getenv("EDITOR")) == NULL)
  89.     {
  90.         if((envedit = getenv("VISUAL")) == NULL)
  91.         {
  92.             envedit = "vi";    /* default editor */
  93.         }
  94.     }
  95.  
  96.     if((term_string = getenv("TERM")) == NULL)
  97.     {
  98.         fprintf(stderr,"\nwish: environment variable \"TERM\" undefined, cannot run!\n");
  99.         exit(1);        
  100.     }
  101.  
  102.     /* init local changable string buffers & pointers */
  103.     
  104.     strcpy(opt_edit, envedit);    /* cp from env to local buffer */
  105.     strcpy(opt_more, envmore);    /* cp from env to local buffer */    
  106.     strcpy(opt_wild, "*");        /* init wildcard buffer ... */
  107.     
  108.     /* second - configure ourselves from users .wishrc */
  109.  
  110.     readrc();            /* read $HOME/.wishrc */
  111.  
  112.     /* adjust for misconfigured wildcards */
  113.     
  114.     if(opt_wild && (strpbrk(opt_wild,WILDCHARS)==NULL))
  115.         opt_wildon = 0;
  116.  
  117.     /* third - configure ourselves from command line parms */
  118.     
  119.     while((--argc > 0) && ( ((*++argv)[0] == '-') || ((*argv)[0] == '+')) )
  120.     {
  121.         if((*argv)[0] == '-')
  122.             optmode = 0;
  123.         else
  124.             optmode = 1;
  125.  
  126.         c = *++argv[0];
  127.  
  128.         while(c)
  129.         {
  130.             switch(c)
  131.             {
  132.                 case 'a':    /* attributes line */
  133.                     if(optmode)
  134.                         opt_attrib = 1;
  135.                     else
  136.                         opt_attrib = 0;
  137.                     break;
  138.                     
  139.                 case 'd':    /* initial preserve dir when cd .. */
  140.                     if(optmode)
  141.                         opt_preserve = 1;
  142.                     else
  143.                         opt_preserve = 0;
  144.                     break;
  145.                     
  146.                 case 'f':    /* NO f-key labels on non-hp terminals */
  147.                     if(optmode)
  148.                         opt_labels = 1;
  149.                     else
  150.                         opt_labels = 0;
  151.                     break;
  152.  
  153.                 case 'l':    /* show links not files */
  154.                     if(optmode)
  155.                         opt_links = 1;
  156.                     else
  157.                         opt_links = 0;
  158.                     break;
  159.  
  160.                 case 'p':    /* display current dir in file window  */
  161.                     if(optmode)
  162.                         opt_point = 1;
  163.                     else
  164.                         opt_point = 0;
  165.                     break;
  166.  
  167.                 case 'r':    /* press return to continue */
  168.                     if(optmode)
  169.                         opt_return = 1;
  170.                     else
  171.                         opt_return = 0;
  172.                     break;
  173.  
  174.                 case 'w':    /* enable wildcards */
  175.                     if(optmode)
  176.                         opt_wildon = 1;
  177.                     else
  178.                         opt_wildon = 0;
  179.                     break;
  180.  
  181.                 case 'c':    /* cdrom mode */
  182.                     if(optmode)
  183.                         opt_cdrom = 1;
  184.                     else
  185.                         opt_cdrom = 0;
  186.                     break;
  187.  
  188.                 case 'C':    /* cdrom progs->files */
  189.                     if(optmode)
  190.                         opt_cdnoprog = 1;
  191.                     else
  192.                         opt_cdnoprog = 0;
  193.                     break;
  194.  
  195.                 case 'n':    /* display dot-filenames */
  196.                     if(optmode)
  197.                         opt_dotnames = 1;
  198.                     else
  199.                         opt_dotnames = 0;
  200.                     break;
  201.  
  202.                 default:
  203.                     fprintf(stderr,"\nwish: illegal option -%c",c);
  204.                     
  205.                 case '?':
  206.                     usage();    /* no return */
  207.             }
  208.         }
  209.     }
  210.  
  211.     if(opt_attrib == 0)        /* if no attrib line, */
  212.         opt_links = 0;        /* no link detection necessary */
  213.     
  214.     /* allocate memory for history */
  215.  
  216.     for(i=0; i < HISLINES; i++)
  217.     {
  218.         if((hislines[i] = (char *)malloc(HISLNLEN)) == NULL)
  219.         {
  220.             fprintf(stderr,"\nwish: history malloc failed, exit ...\n");
  221.             exit(1);
  222.         }
  223.         sprintf(hislines[i],"%02d>",i);        /* write prompt */
  224.     }
  225.  
  226.     cur_fktab = &sys_keys;        /* current fkey label table */
  227.     
  228.     init_header();            /* initialize header string */
  229.     init_time();            /* display time init */
  230.     init_screen();            /* initialize screen */
  231.     init_flabels();            /* init fkey-labels */
  232.     init_history();            /* init commandline history */
  233.     init_files(PRES_NO, NULL);    /* read current directory */
  234.     attribs(1);            /* display attributes */
  235.     update_all();            /* force first screen-update */
  236.  
  237.     switch(termtype)        /* hpux curses workaround */
  238.     {                /* for 2nd bug .....      */
  239.         case TERM_VT1:        /* force header update on */
  240.         case TERM_VT2:        /* dec terminals 2 times  */
  241.         case TERM_VT3:        /* to display inverse!!!! */
  242.         case TERM_PCVT:
  243.             wmove(cmnd_w, C_HEAD, 0);
  244.             waddstr(cmnd_w,headerline);
  245.             wrefresh(cmnd_w);
  246.             header();
  247.             break;
  248.     }
  249.     
  250.     wmove(cmnd_w, C_LINE, curcol());/* cursor to command window */
  251.     wrefresh(cmnd_w);        /* update command window */
  252.  
  253.     bschar = erasechar();        /* get backspace char */
  254.     
  255.     for(;;)
  256.     {
  257.         kchar = getch();    /* get char */
  258.         
  259.         clrerror();        /* if error line in header, clear ! */
  260.  
  261.         if(((kchar >= 0x20) && (kchar <= 0x7e)) ||
  262.            ((kchar >= 0x80) && (kchar <= 0xff)))
  263.         {
  264.             /* printable char's to commandline */
  265.         
  266.             cmdline(kchar);
  267.             wmove(cmnd_w, C_LINE, curcol());            
  268.             wrefresh(cmnd_w);    
  269.             continue;
  270.         }
  271.         else if(kchar == bschar)    /* backspace */
  272.         {
  273.             handlebs();
  274.         }
  275.         else            /* special keys = special actions */
  276.         {
  277.             switch(kchar)
  278.             {
  279.                 case CR:
  280.                     handlecr();
  281.                     update_files();
  282.                     break;
  283.                     
  284.                 case KEY_DC:    /* delete last char */
  285.                     del_char();
  286.                     break;
  287.  
  288.                 case KEY_BACKSPACE:
  289.                     handlebs();
  290.                     break;
  291.                     
  292.                 case KEY_RIGHT:    /* right move cursor */
  293.                 case TAB:
  294.                     move_right();
  295.                     update_files();
  296.                     break;
  297.  
  298.                 case KEY_LEFT:    /* left move cursor */
  299.                 case KEY_BTAB:
  300.                     move_left();
  301.                     update_files();
  302.                     break;
  303.  
  304.                 case KEY_UP:    /* up-move cursor */
  305.                     move_up();
  306.                     update_files();
  307.                     break;
  308.  
  309.                 case KEY_DOWN:    /* down-move cursor */
  310.                     move_down();
  311.                     update_files();
  312.                     break;
  313.  
  314.                 case KEY_HOME:    /* move cursor to first dir */
  315.                     move_home();
  316.                     update_files();
  317.                     break;
  318.  
  319.                 case KEY_LL:    /* move cursor to last file */
  320.                     move_hmdn();
  321.                     update_files();
  322.                     break;
  323.  
  324.                 case KEY_NPAGE:    /* next/previous page */
  325.                     next_page();
  326.                     update_files();
  327.                     break;
  328.                     
  329.                 case KEY_PPAGE:    /* next/previous page */
  330.                     prev_page();
  331.                     update_files();
  332.                     break;
  333.  
  334.                 case KEY_F(1):    /* function key 1 */
  335.                     edit_current();
  336.                     break;
  337.  
  338.                 case KEY_F(2):    /* function key 2 */
  339.                     name_echo();
  340.                     break;
  341.                 
  342.                 case KEY_F(3):    /* function key 3 */
  343.                     help();
  344.                     update_files();
  345.                     break;
  346.                     
  347.                 case KEY_F(4):    /* function key 4 */
  348.                     config();
  349.                     break;
  350.                     
  351.                 case KEY_F(5):    /* function key 5 */
  352.                     tag_current(cur_file);
  353.                     move_right();
  354.                     update_files();
  355.                     break;
  356.  
  357.                 case KEY_F(6):    /* function key 6 */
  358.                     untag_all();
  359.                     update_files();
  360.                     break;
  361.                     
  362.                 case KEY_F(7):    /* function key 7 */
  363.                     break;
  364.                     
  365.                 case KEY_F(8):    /* function key 8 */
  366.                     close_cdir();
  367.                     update_files();
  368.                     break;
  369.  
  370.                 case CNTRL_F:    /* right move cursor */
  371.                     right_line();
  372.                     break;
  373.  
  374.                 case CNTRL_B:    /* left move cursor */
  375.                     left_line();
  376.                     break;
  377.  
  378.                 case CNTRL_P:    /* up-move cursor */
  379.                     prev_line();
  380.                     break;
  381.  
  382.                 case CNTRL_N:    /* down-move cursor */
  383.                     next_line();
  384.                     break;
  385.                     
  386.                 case CNTRL_D:
  387.                     if(cr_on_files())
  388.                     {
  389.                         move(LINES,COLS-1);    /* last display position */
  390.                         free_list();        /* free memory */
  391.                         fini_flabels();        /* normal fkey-labels */
  392.                         endwin();        /* normalize screen */
  393.                         putchar('\n');        /* newline */
  394.                         exit(0);
  395.                     }
  396.                     del_char();
  397.                     break;
  398.                     
  399.                 case CNTRL_K:    /* clear to eol */
  400.                     clear_toeol();
  401.                     break;
  402.  
  403.                 case CNTRL_Y:    /* yank kill buffer */
  404.                     yank();
  405.                     break;
  406.  
  407.                 case CNTRL_A:    /* begin of line */
  408.                     bol_line();
  409.                     break;
  410.  
  411.                 case CNTRL_E:    /* end of line */
  412.                     eol_line();
  413.                     break;
  414.                     
  415.                 case CNTRL_L:    /* refresh */
  416.                     touchwin(curscr);
  417.                     wrefresh(curscr);
  418.                     break;
  419.  
  420.                 case ESC:
  421.                     kchar = getch();    /* get char */
  422.                     switch(kchar)
  423.                     {
  424.                         case '1':    /* function key 1 */
  425.                             edit_current();
  426.                             break;
  427.         
  428.                         case '2':    /* function key 2 */
  429.                             name_echo();
  430.                             break;
  431.                         
  432.                         case '3':    /* function key 3 */
  433.                             help();
  434.                             update_files();
  435.                             break;
  436.                             
  437.                         case '4':    /* function key 4 */
  438.                             config();
  439.                             break;
  440.                             
  441.                         case '5':    /* function key 5 */
  442.                             tag_current(cur_file);
  443.                             move_right();
  444.                             update_files();
  445.                             break;
  446.         
  447.                         case '6':    /* function key 6 */
  448.                             untag_all();
  449.                             update_files();
  450.                             break;
  451.                             
  452.                         case '7':    /* function key 7 */
  453.                             break;
  454.                             
  455.                         case '8':    /* function key 8 */
  456.                             close_cdir();
  457.                             update_files();
  458.                             break;
  459.  
  460.                         case 'n':
  461.                         case 'N':
  462.                             next_page();
  463.                             update_files();
  464.                             break;
  465.  
  466.                         case 'p':
  467.                         case 'P':
  468.                             prev_page();
  469.                             update_files();
  470.                             break;
  471.  
  472.                         case ESC:    /* filename completition */
  473.                             complete();
  474.                             break;
  475.                     }
  476.             }
  477.         }
  478.         wmove(cmnd_w, C_LINE, curcol());
  479.         wrefresh(cmnd_w);
  480.     }
  481. }
  482.  
  483. /*---------------------------------------------------------------------------*
  484.  *    initialize curses and window dimensions
  485.  *---------------------------------------------------------------------------*/
  486. void init_screen(void)            /* initialize everything */
  487. {
  488.     int attrpos;
  489.     
  490.     initscr();            /* curses init */
  491.     nonl();                /* optimize */
  492.     raw();                /* raw input */
  493.     noecho();            /* do not echo input */
  494.     idlok(stdscr,TRUE);        /* use insert/delete */
  495.     keypad(stdscr,TRUE);        /* use special keys */
  496.     meta(stdscr,TRUE);        /* use 8-bit chars */
  497.  
  498.     set_termtype();            /* init terminal dep. stuff */
  499.     
  500.     if((cmnd_w = newwin(C_HEIGHT, COLS, 0, 0)) == NULL)
  501.         fatal("cannot create command window");
  502.  
  503.     fileheight = LINES-C_HEIGHT;
  504.  
  505.     if(opt_labels)
  506.     {
  507.         if((flbl_w = newwin(1, COLS, LINES-1, 0)) == NULL)
  508.             fatal("cannot create fkey-label window");
  509.         fileheight--;
  510.     }
  511.  
  512.     if(opt_attrib)
  513.     {
  514.         fileheight -= 2;
  515.         attrpos = C_HEIGHT+fileheight;
  516.         
  517.         if((attr_w = newwin(2, COLS, attrpos, 0)) == NULL)
  518.             fatal("cannot create attribute window");
  519.     }
  520.  
  521.     if((fst_w = newwin(2, COLS, C_HEIGHT, 0)) == NULL)
  522.         fatal("cannot create file status window");
  523.  
  524.     fileheight -= 2;
  525.     
  526.     if((file_w = newwin(fileheight, COLS, C_HEIGHT+2, 0)) == NULL)
  527.         fatal("cannot create file window");
  528.  
  529.     header();        /* print headerline */
  530.     clearok(curscr,TRUE);
  531. }    
  532.  
  533. /*---------------------------------------------------------------------------*
  534.  *    refresh all windows
  535.  *---------------------------------------------------------------------------*/
  536. void update_all(void)
  537. {
  538.     wnoutrefresh(cmnd_w);
  539.     wnoutrefresh(fst_w);
  540.     touchwin(file_w);    /* after cur_blink() */
  541.     wnoutrefresh(file_w);
  542.     if(opt_attrib)
  543.         wnoutrefresh(attr_w);
  544.     if(opt_labels)
  545.         wnoutrefresh(flbl_w);
  546.     doupdate();
  547. }    
  548.  
  549. /*---------------------------------------------------------------------------*
  550.  *    refresh file window and attrib window
  551.  *---------------------------------------------------------------------------*/
  552. void update_files(void)
  553. {
  554.     wnoutrefresh(file_w);
  555.     if(opt_attrib)
  556.         wnoutrefresh(attr_w);
  557.     if(opt_labels)
  558.         wnoutrefresh(flbl_w);
  559.     doupdate();
  560. }    
  561.  
  562. /*---------------------------------------------------------------------------*
  563.  *    find out terminal-type and initialize terminal specific things
  564.  *---------------------------------------------------------------------------*/
  565. void set_termtype(void)
  566. {
  567.     static char initvt[] = { ESC, ')', '0', '\0'};
  568.  
  569.     if(ceol_standout_glitch)        /* HP-Terminal */
  570.     {
  571.         opt_labels = 0;            /* no virtual fkey-labels */
  572.         if(!strcmp(term_string,"hpterm")) /* X11 hpterm */
  573.             termtype = TERM_HPX;
  574.         else
  575.             termtype = TERM_HP;
  576.     }
  577.  
  578.     else if(!strncmp(term_string,"vt1",3))    /* DEC VT1xx ?? */
  579.     {
  580.         opt_labels = 1;            /* virtual fkey-labels */
  581.         termtype = TERM_VT1;
  582.     }
  583.  
  584.     else if(!strncmp(term_string,"vt220",5))/* DEC VT220 ?? */
  585.     {
  586.         opt_labels = 1;            /* virtual fkey-labels */
  587.         write(2, initvt, 3);
  588.         termtype = TERM_VT2;
  589.     }
  590.  
  591.     else if(!strncmp(term_string,"vt320",5))/* DEC VT320 ?? */
  592.     {
  593.         opt_labels = 1;            /* virtual fkey-labels */
  594.         write(2, initvt, 3);
  595.         termtype = TERM_VT3;
  596.     }
  597.  
  598.     else if(!strncmp(term_string,"pcvt",4))    /* 386BSD pcvt ?? */
  599.     {
  600.         opt_labels = 0;            /* real fkey-labels */
  601.         write(2, initvt, 3);
  602.         termtype = TERM_PCVT;
  603.     }
  604.  
  605.     else                    /* dumb thing .. */
  606.     {
  607.         termtype = TERM_DUMB;
  608.     }
  609. }
  610.  
  611. /*---------------------------------- EOF ----------------------------------*/
  612.