pat@kai.com (Patrick J. Wolfe) (05/21/91)
Submitted-by: Patrick J. Wolfe <pat@kai.com> Posting-number: Volume 20, Issue 2 Archive-name: scan/part02 #! /bin/sh # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: filemenu.c keymenu.c optionmenu.c readrc.c userfuncs.c # Wrapped by kent@sparky on Tue May 21 00:34:20 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 2 (of 3)."' if test -f 'filemenu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'filemenu.c'\" else echo shar: Extracting \"'filemenu.c'\" \(9892 characters\) sed "s/^X//" >'filemenu.c' <<'END_OF_FILE' X/* X * Original Author: Patrick Wolfe (pat@kai.com, kailand!pat) X * X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe. X * X * Permission is hereby granted to copy, distribute or otherwise X * use any part of this package as long as you do not try to make X * money from it or pretend that you wrote it. This copyright X * notice must be maintained in any copy made. X * X * Use of this software constitutes acceptance for use in an AS IS X * condition. There are NO warranties with regard to this software. X * In no event shall the author be liable for any damages whatsoever X * arising out of or in connection with the use or performance of this X * software. Any use of this software is at the user's own risk. X * X * If you make modifications to this software that you feel X * increases it usefulness for the rest of the community, please X * email the changes, enhancements, bug fixes as well as any and X * all ideas to me. This software is going to be maintained and X * enhanced as deemed necessary by the community. X * X * Patrick J. Wolfe X * uunet!uiucuxc!kailand!pwolfe X * pwolfe@kailand.kai.com X */ X X X#include "config.h" X#define CURSORCOL 56 X Xextern SIGTYPE die(); Xextern struct key_entry keytab[]; Xextern struct dblock cwd[]; Xextern struct namelist lidlist[], gidlist[]; Xextern int opt_show_filetype, opt_rm_prompt, opt_pager_pause, hidden_ctr; Xextern char *loginid, *editor, *pager, *shellpgm, *homedir, currdir[], prevdir[]; X XWINDOW *headwin, *datawin, *helpwin; Xlong sixmonthsago; Xint lastptr, topptr, curptr, century = 19; Xchar errormsg[256]; X Xchar *monthtable[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; Xstatic char *dowtable[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; Xstatic char *helpline = " Use arrow keys or j/k to move pointer - press \"?\" for help "; Xstatic int msgonscreen = 0; X X X/* ---------------------------------------------------------------------------- */ X/* menu processing routines */ X/* ---------------------------------------------------------------------------- */ X X Xint Xread_cmdline (winptr, row, col, cmdline, maxlen, prompt) XWINDOW *winptr; Xint row, col, maxlen; Xchar *cmdline, *prompt; X{ Xint c; Xint cmdlen = 0; Xint promptlen = col + strlen(prompt); X Xwmove (winptr, row, col); Xwclrtoeol (winptr); Xwmove (winptr, row, col); Xwstandout (winptr); Xwaddstr (winptr, prompt); Xwstandend (winptr); Xwmove (winptr, row, promptlen); Xwrefresh (winptr); X Xwhile (1) { X c = my_getch (winptr); X switch (c) { X X case ControlU: /* clear the command line */ X if (cmdlen > 0) { X cmdlen = 0; X cmdline[cmdlen] = '\0'; X wmove (winptr, row, promptlen); X wclrtoeol (winptr); X wmove (winptr, row, promptlen); X wrefresh (winptr); X } X break; X X case ControlJ: X case ControlM: X return cmdlen; X X case ControlH: X case Delete: X if (cmdlen > 0) { X cmdline[--cmdlen] = '\0'; X wmove (winptr, row, promptlen + cmdlen); X wclrtoeol (winptr); X wmove (winptr, row, promptlen + cmdlen); X wrefresh (winptr); X } X break; X X default: /* type a command on the command entry line */ X if ((isprint(c)) && (cmdlen < maxlen)) { X cmdline[cmdlen++] = c; X cmdline[cmdlen] = '\0'; X wmove (winptr, row, promptlen + cmdlen - 1); X waddch (winptr, c); X wmove (winptr, row, promptlen + cmdlen); X wrefresh (winptr); X } X else { X beep (); X } X } X } X} X X Xmsgupdate () X{ Xif ((! msgonscreen) && (errormsg[0] == '\0')) X return; Xwmove (headwin, 2, 0); Xwclrtoeol (headwin); Xif (errormsg[0] != '\0') { X wmove (headwin, 2, 0); X wstandout (headwin); X waddstr (headwin, errormsg); X wstandend (headwin); X errormsg[0] = '\0'; X msgonscreen = 1; X } Xelse { X msgonscreen = 0; X } Xwrefresh (headwin); X} X X Xmenu_update () X{ Xstruct timeval tp; Xstruct tm *today; Xint row, ptr; Xchar subname[256]; X X/* get today's date */ Xgettimeofday (&tp, 0); Xtoday = localtime (&tp.tv_sec); Xsixmonthsago = tp.tv_sec - (60 * 60 * 24 * 180); /* time 180 days (6 months) ago */ X X/* update the date and time in the top header line */ Xmvwprintw (headwin, 0, 57, "%3s %3s %2d, %02d%02d %2d:%02d", dowtable[today->tm_wday], X monthtable[today->tm_mon], today->tm_mday, century, today->tm_year, today->tm_hour, today->tm_min); Xwrefresh (headwin); Xmsgupdate (); X Xwmove (datawin, 0, 0); Xwclrtobot (datawin); X X/* draw the menu lines on the screen */ Xfor (row = 0; (row < PAGESIZE) && ((topptr + row) <= lastptr) ; row++) { X ptr = topptr + row; X X if (cwd[ptr].size == -1) X statfile (ptr); /* only stat files if we need to */ X X wmove (datawin, row, 0); X if (cwd[ptr].selected) X wstandout (datawin); X X if (cwd[ptr].size == -1) { X /* couldn't stat - display the error message stored in link */ X mvwprintw (datawin, row, 0, "%-55s ", cwd[ptr].link); X /* display file name */ X if (strlen (cwd[ptr].name) < (COLS - 55)) { X wprintw (datawin, "%s", cwd[ptr].name); X } X else { X strncpy (subname, cwd[ptr].name, COLS-58); X cwd[ptr].name[COLS-58] = '.'; X cwd[ptr].name[COLS-57] = '.'; X cwd[ptr].name[COLS-56] = '.'; X cwd[ptr].name[COLS-55] = '\n'; X waddstr (datawin, subname); X } X } X else { X /* display perms, owner, group, size and modification time */ X wprintw (datawin, "%10s %-8s %-10s %9d %-12s ", cwd[ptr].perms, lidlist[cwd[ptr].owner].name, X gidlist[cwd[ptr].group].name, cwd[ptr].size, cwd[ptr].modtime); X X if (ptr == curptr) { X if (cwd[curptr].selected) X wstandend (datawin); X else X wstandout (datawin); X /* only highlight the pointer if the current file is NOT selected */ X waddstr (datawin, "==>"); X if (cwd[curptr].selected) X wstandout (datawin); X else X wstandend (datawin); X waddch (datawin, ' '); X } X else X waddstr (datawin, " "); X X /* display file name */ X if (strlen (cwd[ptr].name) < (COLS - 55)) { X wprintw (datawin, "%s%s", cwd[ptr].name, cwd[ptr].link); X } X else { X strncpy (subname, cwd[ptr].name, COLS-58); X cwd[ptr].name[COLS-58] = '.'; X cwd[ptr].name[COLS-57] = '.'; X cwd[ptr].name[COLS-56] = '.'; X cwd[ptr].name[COLS-55] = '\n'; X waddstr (datawin, subname); X } X } X X if (cwd[ptr].selected) X wstandend (datawin); X } X X Xwrefresh (datawin); X} X X Xmenu_move (distance) Xint distance; X{ Xint oldcur; X Xoldcur = curptr; Xcurptr += distance; X Xif (curptr < 0) { /* sanity check */ X curptr = 0; X } Xelse if (curptr > lastptr) { X curptr = lastptr; X } X X/* adjust top of screen, if neccessary */ Xif ((curptr < (topptr - PAGESIZE)) X || (curptr > (topptr + PAGESIZE + PAGESIZE))) { X topptr = curptr; /* if moving further than one page, put the new current on top */ X } Xelse if (curptr < topptr) { X topptr -= PAGESIZE; /* moving to previous page */ X if (topptr < 0) { X topptr = 0; X } X } Xelse if (curptr > (topptr + PAGESIZE - 1)) { X topptr += PAGESIZE; /* moving to next page */ X if (topptr > ((lastptr - PAGESIZE) + 1)) { X topptr = (lastptr - PAGESIZE) + 1; X if (topptr < 0) { X topptr = 0; X } X } X } X/* if we staying on the same page, just move the pointer */ Xelse { X msgupdate (); X /* erase the old pointer */ X wmove (datawin, oldcur - topptr, CURSORCOL); X if (cwd[oldcur].selected == 1) X wstandout (datawin); X waddstr (datawin, " "); X if (cwd[oldcur].selected == 1) X wstandend (datawin); X /* draw the new pointer */ X wmove (datawin, curptr - topptr, CURSORCOL); X if (cwd[curptr].selected == 0) X wstandout (datawin); X waddstr (datawin, "==>"); X if (cwd[curptr].selected == 0) X wstandend (datawin); X wrefresh (datawin); X return; X } X Xmenu_update (); X} X X Xmenu_scroll (distance) Xint distance; X{ Xtopptr += distance; Xif (topptr > ((lastptr - PAGESIZE) + 1)) { X topptr = (lastptr - PAGESIZE) + 1; X } Xif (topptr < 0) { X topptr = 0; X } Xif (curptr < topptr) { X curptr = topptr; X } Xelse if (curptr > (topptr + PAGESIZE - 1)) { X curptr = topptr; X } Xmenu_update (); X} X X Xredraw_menu () X{ Xint len; X Xclear (); Xrefresh (); Xwmove (headwin, 0, 0); Xwclrtobot (headwin); X X/* draw the header line */ Xwmove (headwin, 0, 0); Xmvwprintw (headwin, 0, 0, "%-44s %-8s", PGM_VERSION, loginid); Xmvwaddstr (headwin, 1, 0, "Directory: "); Xlen = strlen(currdir); Xif (len > COLS - 23) { X waddstr (headwin, "..."); X waddstr (headwin, &currdir[(len - COLS) - 27]); X } Xelse { X waddstr (headwin, currdir); X } Xwprintw (headwin, " - %3d files", lastptr + hidden_ctr + 1); Xmvwprintw (headwin, 3, 0, "%-10s %-8s %-10s %9s %12s %s", X "mode", "owner", "group", "size", "modified", "filename"); Xmvwprintw (headwin, 4, 0, "%-10s %-8s %-10s %9s %12s %s", X "----", "-----", "-----", "----", "--------", "--------"); X Xmenu_update (); X Xredraw_help (); X} X X Xredraw_help () X{ Xwmove (helpwin, 0, 0); Xwclrtoeol (helpwin); Xwmove (helpwin, 0, 0); Xwstandout (helpwin); Xwaddstr (helpwin, helpline); Xwstandend (helpwin); Xwrefresh (helpwin); X} X X Xmain_loop () X{ Xint c; X Xinitscr (); /* initialize curses */ Xsignal (SIGHUP, die); /* trap signal 1, hangup */ Xsignal (SIGINT, die); /* trap signal 2, interrupt */ Xsignal (SIGQUIT, die); /* trap signal 3, quit */ Xsignal (SIGTERM, die); /* trap signal 15, software termination */ Xif (LINES < 10) { X fprintf (stderr, "\r\nterminal is too small - 10 lines minimum\r\n"); X die (); X } XPAGESIZE = LINES - 6; /* size of file menu */ Xnoecho (); /* curses should not echo keys as they are typed */ Xnonl (); /* disable cr/lf mapping */ Xcrmode (); /* turn on cbreak mode */ Xheadwin = newwin (5, COLS, 0, 0); Xdatawin = newwin (PAGESIZE, COLS, 5, 0); Xhelpwin = newwin (1, COLS, PAGESIZE + 5, 0); X#ifdef SYSVcurses Xidlok (datawin, TRUE); X#endif X Xcurptr = topptr = 0; X/* start off by reading the current directory */ Xdo_chdir ("."); X Xwhile (1) { X c = my_getch (headwin); X if ((keytab[c].type == KEY_FUNC) && (keytab[c].pntr != (voidptr) NULL)) { X ((Function *) keytab[c].pntr) (c); X } X else if ((keytab[c].type == KEY_CMD) && (keytab[c].pntr != (voidptr) NULL)) { X do_cmd ((char *) keytab[c].pntr, keytab[c].options); X } X else { X beep (); X } X } X/* NOTREACHED */ X} END_OF_FILE if test 9892 -ne `wc -c <'filemenu.c'`; then echo shar: \"'filemenu.c'\" unpacked with wrong size! fi # end of 'filemenu.c' fi if test -f 'keymenu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'keymenu.c'\" else echo shar: Extracting \"'keymenu.c'\" \(10562 characters\) sed "s/^X//" >'keymenu.c' <<'END_OF_FILE' X X/* X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe. X * X * Permission is hereby granted to copy, distribute or otherwise X * use any part of this package as long as you do not try to make X * money from it or pretend that you wrote it. This copyright X * notice must be maintained in any copy made. X * X * Use of this software constitutes acceptance for use in an AS IS X * condition. There are NO warranties with regard to this software. X * In no event shall the author be liable for any damages whatsoever X * arising out of or in connection with the use or performance of this X * software. Any use of this software is at the user's own risk. X * X * If you make modifications to this software that you feel X * increases it usefulness for the rest of the community, please X * email the changes, enhancements, bug fixes as well as any and X * all ideas to me. This software is going to be maintained and X * enhanced as deemed necessary by the community. X * X * Patrick J. Wolfe X * uunet!uiucuxc!kailand!pwolfe X * pwolfe@kailand.kai.com X */ X X#include "config.h" Xextern struct funcname_entry funcname_table[]; Xextern struct keydef_entry keydef_table[]; Xextern struct key_entry keytab[]; Xextern int read_cmdline (); X Xstatic void redraw_data (); X Xint keydef_changed; /* flag to indicate some options were changed */ Xstatic WINDOW *header_window, *data_window, *help_window; Xstatic int top = 0; /* index of top option on screen (retained between invokations) */ Xstatic int current = 0; /* index of current option (retained between invokations) */ Xstatic int last = SIZEKEYTAB - 1; /* index of last option in option_table (calculated when first run) */ X Xstatic void Xdefine_a_key (c1) Xchar c1; X{ Xvoidptr func; Xint key, c, k, len, options; Xchar *ptr2, command[256]; X Xwmove (help_window, 0, 0); Xwclrtobot (help_window); Xwrefresh (help_window); X Xwmove (header_window, 2, 0); Xwclrtobot (header_window); Xwrefresh (header_window); X Xwmove (data_window, 0, 0); Xwclrtobot (data_window); Xmvwprintw (data_window, 3, 0, "Press the key you would like to %sefine,", (c1 == 'U' ? "Und" : "D")); Xmvwaddstr (data_window, 4, 0, "or press \"q\" to not change anything"); Xwrefresh (data_window); X Xkey = my_getch (data_window); Xif ((key == 'q') || (key == 'Q')) { X redraw_all (); X return; X } X Xif (c1 == 'U') { /* undefine key and get out now */ X keytab[key].type = KEY_UNDEF; X redraw_all (); X return; X } X Xwmove (header_window, 3, 0); Xwclrtoeol (header_window); Xmvwaddstr (header_window, 3, 0, "Defining key "); X Xif ((key >= '!') && (key <= '~')) { X waddch (header_window, '"'); X waddch (header_window, key); X waddch (header_window, '"'); X } Xelse { X for (k = 0; (keydef_table[k].name != NULL) && (keydef_table[k].value != key); k++); X if (keydef_table[k].name != NULL) { X waddstr (header_window, keydef_table[k].name); X } X } Xwprintw (header_window, " (octal value %03o)", key); Xwrefresh (header_window); X Xwmove (data_window, 3, 0); Xwclrtoeol (data_window); X Xmvwaddstr (data_window, 3, 0, "Press C to make this key enter a command,"); Xmvwaddstr (data_window, 4, 0, " F to make this key execute a builtin function"); Xmvwaddstr (data_window, 5, 0, " Q to quit without defining a key"); Xwrefresh (data_window); X Xfor (c = my_getch (data_window); (c != 'c') && (c != 'C') && (c != 'f') && (c != 'F') && (c != 'q') && (c != 'Q'); c = my_getch (data_window)); X Xwmove (data_window, 0, 0); Xwclrtobot (data_window); Xwrefresh (data_window); Xwmove (header_window, 0, 0); Xwclrtobot (header_window); Xwrefresh (header_window); X Xif ((c == 'q') || (c == 'Q')) { /* quit - do not define a key */ X redraw_all (); X return; X } X Xif ((c == 'f') || (c == 'F')) { /* defining a key to execute a builtin function */ X func = (voidptr) function_menu (); X if (func != (voidptr) NULL) { X keytab[key].type = KEY_FUNC; X keytab[key].pntr = func; X keydef_changed = 1; X } X redraw_all (); X return; X } X Xwmove (data_window, 3, 0); /* defining a key to execute a command */ Xwclrtobot (data_window); Xoptions = 0; X Xmvwaddstr (data_window, 3, 0, "Pause and ask before running the command? (Y/N) "); Xwrefresh (data_window); Xfor (c = my_getch (data_window); (c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N'); c = my_getch (data_window)); Xif ((c == 'y') || (c == 'Y')) { X waddch (data_window, 'Y'); X options |= OPT_VERIFY; X } Xelse X waddch (data_window, 'N'); X Xmvwaddstr (data_window, 4, 0, "Pause after the command finishes? (Y/N) "); Xwrefresh (data_window); Xfor (c = my_getch (data_window); (c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N'); c = my_getch (data_window)); Xif ((c == 'y') || (c == 'Y')) { X waddch (data_window, 'Y'); X options |= OPT_WAIT; X } Xelse X waddch (data_window, 'N'); X Xmvwaddstr (data_window, 5, 0, "Append the names of the current file, all tagged files or no files to the command? (C/T/N)"); Xwrefresh (data_window); Xfor (c = my_getch (data_window); X (c != 'c') && (c != 'C') && (c != 't') && (c != 'T') && (c != 'n') && (c != 'N'); X c = my_getch (data_window)); Xif ((c == 'c') || (c == 'C')) { X waddch (data_window, 'C'); X options |= OPT_TAGCUR; X } Xelse if ((c == 't') || (c == 'T')) { X waddch (data_window, 'T'); X options |= OPT_TAGALL; X } Xelse X waddch (data_window, 'N'); X Xlen = read_cmdline (data_window, 6, 0, command, COLS - 10, "Command? "); Xif (len > 0) { X keytab[key].type = KEY_CMD; X keytab[key].options = options; X ptr2 = (char *) malloc(len + 1); X strcpy (ptr2, command); X keytab[key].pntr = (voidptr) ptr2; X keydef_changed = 1; X } X Xredraw_all (); X} X X Xstatic Xdown_one_line () X{ Xif (current < last) { X current++; X if (current > (top + 14)) { X top += 14; X if (top >= (last - 14)) { X top = last - 14; X if (top < 0) { X top = 0; X } X } X } X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xup_one_line () X{ Xif (current > 0) { X current--; X if (current < top) { X top -= 14; X if (top < 0) { X top = 0; X } X } X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xdown_one_screen () X{ Xif (top < (last - 14)) { X top += 15; X if (top >= (last - 14)) { X top = last - 14; X if (top < 0) { X top = 0; X } X } X current = top; X redraw_data (); X } Xelse if (current < last) { X current = last; X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xup_one_screen () X{ Xif (top > 0) { X top -= 15; X if (top < 0) { X top = 0; X } X current = top + 14; X if (current > last) { X current = last; X } X redraw_data (); X } Xelse if (current > 0) { X current = 0; X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic void Xredraw_data () X{ Xint row, key, k; X Xwmove (data_window, 0, 0); Xwclrtobot (data_window); Xfor (row = 0, key = top; (key <= last) && (row < 15); key++, row++) { X if (key == current) { X wstandout (data_window); X } X X wmove (data_window, row, 0); X wprintw (data_window, "%03o", key); X X if ((key >= '!') && (key <= '~')) { X mvwaddch (data_window, row, 7, key); X } X else { X for (k = 0; (keydef_table[k].name != NULL) && (keydef_table[k].value != key); k++); X if (keydef_table[k].name != NULL) { X mvwaddstr (data_window, row, 7, keydef_table[k].name); X } X } X X wmove (data_window, row, 25); X waddch (data_window, ' '); X if (keytab[key].type == KEY_FUNC) { X for (k = 0; (funcname_table[k].kfunc != NULL) && (funcname_table[k].kfunc != (Function *) keytab[key].pntr); k++); X if (funcname_table[k].kfunc == NULL) { X waddstr (data_window, "func UNKNOWN"); X } X else { X waddstr (data_window, "func "); X waddstr (data_window, funcname_table[k].name); X } X } X else if (keytab[key].type == KEY_CMD) { X waddstr (data_window, "cmd "); X if (keytab[key].options & OPT_TAGALL) { X waddstr (data_window, "-all "); X } X else if (keytab[key].options & OPT_TAGCUR) { X waddstr (data_window, "-cur "); X } X else { X waddstr (data_window, "-none "); X } X if (keytab[key].options & OPT_VERIFY) { X waddstr (data_window, "-ver "); X } X else { X waddstr (data_window, "-nover "); X } X if (keytab[key].options & OPT_WAIT) { X waddstr (data_window, "-wait "); X } X else { X waddstr (data_window, "-nowait "); X } X if (keytab[key].options & OPT_WAITERR) { X waddstr (data_window, "-err "); X } X else { X waddstr (data_window, "-noerr "); X } X waddstr (data_window, (char *) keytab[key].pntr); X } X else { X waddstr (data_window, "undefined"); X } X X if (key == current) { X wstandend (data_window); X } X } Xwrefresh (data_window); X} X X Xstatic Xredraw_all () X{ Xwmove (header_window, 0, 0); Xwclrtobot (header_window); Xwmove (header_window, 1, 10); Xwstandout (header_window); Xwaddstr (header_window, PGM_VERSION); Xwaddstr (header_window, " Key Definition Menu"); Xwstandend (header_window); Xwmove (header_window, 3, 3); Xwprintw (header_window, "%-5s %-20s %s", "key", "key name", "definition"); Xwmove (header_window, 4, 0); Xwaddstr (header_window, "------------------------------------------------------------------------------"); Xwrefresh (header_window); X Xredraw_data (); X Xwmove (help_window, 0, 0); Xwclrtobot (help_window); Xwmove (help_window, 0, 0); Xwaddstr (help_window, "+----------------------------------------------------------------------------+"); Xwmove (help_window, 1, 0); Xwaddstr (help_window, "| use ^F, ^B, j, k and/or the arrow keys to move around the display |"); Xwmove (help_window, 2, 0); Xwaddstr (help_window, "| D = define a key, U = undefine a key, Q = return to previous menu |"); Xwmove (help_window, 3, 0); Xwaddstr (help_window, "+----------------------------------------------------------------------------+"); Xwrefresh (help_window); X} X X Xint Xkeydef_menu () X{ Xint c; Xkeydef_changed = 0; X Xheader_window = newwin (5, 80, 0, 0); Xdata_window = newwin (15, 80, 5, 0); Xhelp_window = newwin (4, 80, 20, 0); X#ifdef SYSVcurses Xidlok (data_window, TRUE); X#endif Xredraw_all (); X Xwhile (1) { X c = my_getch (header_window); X switch (c) { X X case ControlB: X case KEY_PPAGE: X case KEY_PrevScreen: X up_one_screen (); X break; X X case ControlF: X case KEY_NPAGE: X case KEY_NextScreen: X down_one_screen (); X break; X X case 'D': X case 'U': X define_a_key (c); X break; X X case 'k': X case KEY_UP: X case ControlP: X up_one_line (); X break; X X case 'j': X case KEY_DOWN: X case ControlN: X down_one_line (); X break; X X case 'q': X case 'Q': X wmove (header_window, 0, 0); X wclrtobot (header_window); X wrefresh (header_window); X delwin (header_window); X wmove (data_window, 0, 0); X wclrtobot (data_window); X wrefresh (data_window); X delwin (data_window); X wmove (help_window, 0, 0); X wclrtobot (help_window); X wrefresh (help_window); X delwin (help_window); X return; X X case ControlL: X case ControlR: X redraw_all (); X break; X X default: X beep(); X } X } X} END_OF_FILE if test 10562 -ne `wc -c <'keymenu.c'`; then echo shar: \"'keymenu.c'\" unpacked with wrong size! fi # end of 'keymenu.c' fi if test -f 'optionmenu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'optionmenu.c'\" else echo shar: Extracting \"'optionmenu.c'\" \(6422 characters\) sed "s/^X//" >'optionmenu.c' <<'END_OF_FILE' X X/* X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe. X * X * Permission is hereby granted to copy, distribute or otherwise X * use any part of this package as long as you do not try to make X * money from it or pretend that you wrote it. This copyright X * notice must be maintained in any copy made. X * X * Use of this software constitutes acceptance for use in an AS IS X * condition. There are NO warranties with regard to this software. X * In no event shall the author be liable for any damages whatsoever X * arising out of or in connection with the use or performance of this X * software. Any use of this software is at the user's own risk. X * X * If you make modifications to this software that you feel X * increases it usefulness for the rest of the community, please X * email the changes, enhancements, bug fixes as well as any and X * all ideas to me. This software is going to be maintained and X * enhanced as deemed necessary by the community. X * X * Patrick J. Wolfe X * uunet!uiucuxc!kailand!pwolfe X * pwolfe@kailand.kai.com X */ X X#include "config.h" X Xextern struct option_entry option_table[]; Xextern char *true_false[], *dot_order[], *dir_order[]; X Xint options_changed; /* flag to indicate some options were changed */ Xstatic WINDOW *header_window, *data_window, *help_window; Xstatic int top = 0; /* index of top option on screen (retained between invokations) */ Xstatic int current = 0; /* index of current option (retained between invokations) */ Xstatic int last; /* index of last option in option_table (calculated when first run) */ X X Xstatic void Xredraw_data () X{ Xint i, j, k; Xint *variable; Xchar **value_table; X Xwmove (data_window, 0, 0); Xwclrtobot (data_window); Xif (last > -1) { X for (i = 0, j = top; (j <= last) && (i < 15); i++, j++) { X if (j == current) { X wstandout (data_window); X } X X wmove (data_window, i, 3); X wprintw (data_window, "%-15s", option_table[j].name); X X if (j == current) { X wstandend (data_window); X } X X waddstr (data_window, " "); X X variable = option_table[j].variable; X value_table = option_table[j].value_table; X for (k = 0; value_table[k] != NULL; k++) { X waddstr (data_window, " "); X if (*variable == k) { X wstandout (data_window); X waddch (data_window, '>'); X } X else { X waddch (data_window, ' '); X } X wprintw (data_window, "%-10s", value_table[k]); X if (*variable == k) { X waddch (data_window, '<'); X wstandend (data_window); X } X else { X waddch (data_window, ' '); X } X } X } X } Xwrefresh (data_window); X} X X Xstatic Xright_one_value () X{ Xint *variable; Xchar **value_table; X Xvariable = option_table[current].variable; Xvalue_table = option_table[current].value_table; Xif (value_table[*variable + 1] == NULL) { X beep (); X } Xelse { X *variable = *variable + 1; X options_changed = 1; X redraw_data (); X } X} X X Xstatic Xleft_one_value () X{ Xint *variable; X Xvariable = option_table[current].variable; Xif (*variable == 0) { X beep (); X } Xelse { X *variable = *variable - 1; X options_changed = 1; X redraw_data (); X } X} X X Xstatic Xredraw_all () X{ Xwmove (header_window, 0, 0); Xwclrtobot (header_window); Xwmove (header_window, 1, 10); Xwstandout (header_window); Xwaddstr (header_window, PGM_VERSION); Xwaddstr (header_window, " Options Menu"); Xwstandend (header_window); Xwmove (header_window, 3, 3); Xwprintw (header_window, "%-15s %s", "option name", "values"); Xwmove (header_window, 4, 0); Xwaddstr (header_window, "------------------------------------------------------------------------------"); Xwrefresh (header_window); X Xredraw_data (); X Xwmove (help_window, 0, 0); Xwclrtobot (help_window); Xwmove (help_window, 0, 0); Xwaddstr (help_window, "+----------------------------------------------------------------------------+"); Xwmove (help_window, 1, 0); Xwaddstr (help_window, "| use arrow keys to select and change values of options |"); Xwmove (help_window, 2, 0); Xwaddstr (help_window, "| press Q to return to the previous menu |"); Xwmove (help_window, 3, 0); Xwaddstr (help_window, "+----------------------------------------------------------------------------+"); Xwrefresh (help_window); X} X X Xstatic Xdown_one_line () X{ Xif (current < last) { X current++; X if (current > (top + 14)) { X top += 14; X if (top >= (last - 14)) { X top = last - 14; X if (top < 0) { X top = 0; X } X } X } X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xup_one_line () X{ Xif (current > 0) { X current--; X if (current < top) { X top -= 14; X if (top < 0) { X top = 0; X } X } X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xdown_one_screen () X{ Xif (top < (last - 14)) { X top += 15; X if (top >= (last - 14)) { X top = last - 14; X if (top < 0) { X top = 0; X } X } X current = top; X redraw_data (); X } Xelse if (current < last) { X current = last; X redraw_data (); X } Xelse { X beep(); X } X} X X Xstatic Xup_one_screen () X{ Xif (top > 0) { X top -= 15; X if (top < 0) { X top = 0; X } X current = top + 14; X if (current > last) { X current = last; X } X redraw_data (); X } Xelse if (current > 0) { X current = 0; X redraw_data (); X } Xelse { X beep(); X } X} X X Xint Xoptions_menu () X{ Xint c; Xoptions_changed = 0; X X/* find index of last option */ Xfor (last = 0; option_table[last].name != NULL; last++); Xlast--; Xheader_window = newwin (5, 80, 0, 0); Xdata_window = newwin (15, 80, 5, 0); Xhelp_window = newwin (4, 80, 20, 0); X#ifdef SYSVcurses Xidlok (data_window, TRUE); X#endif Xredraw_all (); X Xwhile (1) { X c = my_getch (header_window); X switch (c) { X X case ControlB: X case KEY_PPAGE: X case KEY_PrevScreen: X up_one_screen (); X break; X X case ControlF: X case KEY_NPAGE: X case KEY_NextScreen: X down_one_screen (); X break; X X case 'k': X case KEY_UP: X case ControlP: X up_one_line (); X break; X X case 'j': X case KEY_DOWN: X case ControlN: X down_one_line (); X break; X X case 'h': X case KEY_LEFT: X left_one_value (); X break; X X case 'l': X case KEY_RIGHT: X right_one_value (); X break; X X case 'q': X case 'Q': X wmove (header_window, 0, 0); X wclrtobot (header_window); X wrefresh (header_window); X delwin (header_window); X wmove (data_window, 0, 0); X wclrtobot (data_window); X wrefresh (data_window); X delwin (data_window); X wmove (help_window, 0, 0); X wclrtobot (help_window); X wrefresh (help_window); X delwin (help_window); X return; X X case ControlL: X case ControlR: X redraw_all (); X break; X X default: X beep(); X } X } X} END_OF_FILE if test 6422 -ne `wc -c <'optionmenu.c'`; then echo shar: \"'optionmenu.c'\" unpacked with wrong size! fi # end of 'optionmenu.c' fi if test -f 'readrc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'readrc.c'\" else echo shar: Extracting \"'readrc.c'\" \(12164 characters\) sed "s/^X//" >'readrc.c' <<'END_OF_FILE' X/* X * readrc.c X * X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe. X * X * Permission is hereby granted to copy, distribute or otherwise X * use any part of this package as long as you do not try to make X * money from it or pretend that you wrote it. This copyright X * notice must be maintained in any copy made. X * X * Use of this software constitutes acceptance for use in an AS IS X * condition. There are NO warranties with regard to this software. X * In no event shall the author be liable for any damages whatsoever X * arising out of or in connection with the use or performance of this X * software. Any use of this software is at the user's own risk. X * X * If you make modifications to this software that you feel X * increases it usefulness for the rest of the community, please X * email the changes, enhancements, bug fixes as well as any and X * all ideas to me. This software is going to be maintained and X * enhanced as deemed necessary by the community. X * X * Patrick J. Wolfe X * uunet!uiucuxc!kailand!pwolfe X * pwolfe@kailand.kai.com X */ X X X#include "config.h" X#include "readrc.h" X Xextern struct key_entry keytab[], default_keytab[]; Xextern int century; Xextern char rcfilename[], *loginid, errormsg[]; X Xint rcerrors = 0; X X Xstatic void Xrcerrmsg (filename, lineno, msg, arg) Xint lineno; Xchar *filename, *msg, *arg; X{ Xrcerrors++; Xif (rcerrors == 1) { X fprintf (stderr, "\r\nerror in scan initfile %s:\n", filename); X } Xfprintf (stderr, "line %d: %s", lineno, msg); Xif (arg[0] != '\0') { X fprintf (stderr, ": \"%s\"", arg); X } Xfputc ('\n', stderr); X} X X Xstatic void Xsetoption (filename, lineno, ptr1) Xchar *filename, *ptr1; Xint lineno; X{ Xint ctr, *variable; Xchar *ptr2; Xchar **value_table; X X/* skip whitespace */ Xfor (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); Xif (*ptr1 == '\n') { X rcerrmsg (filename, lineno, "missing option name", ""); X return; X } X X/* find end of variable name */ Xfor (ptr2 = ptr1; (*ptr2 != '\n') && !isspace(*ptr2); *ptr2++); Xif (*ptr2 == '\n') { X rcerrmsg (filename, lineno, "missing value", ""); X return; X } X*ptr2 = '\0'; X X/* validate option name */ Xfor (ctr = 0; (option_table[ctr].name != NULL) && (strcmp (option_table[ctr].name, ptr1) != 0); ctr++); Xif (option_table[ctr].name == NULL) { X rcerrmsg (filename, lineno, "invalid option name", ptr1); X return; X } Xvariable = option_table[ctr].variable; Xvalue_table = option_table[ctr].value_table; X X/* skip whitespace and equals sign */ Xfor (ptr1 = ptr2, ptr1++; (*ptr1 != '\n') && (isspace(*ptr1) || (*ptr1 == '=')); ptr1++); Xif (*ptr1 == '\n') { X rcerrmsg (filename, lineno, "missing value", ""); X return; X } X X/* find end of value */ Xfor (ptr2 = ptr1; (*ptr2 != '\n') && !isspace(*ptr2); *ptr2++); X*ptr2 = '\0'; X X/* check value table */ Xfor (ctr = 0; (value_table[ctr] != NULL) && (strcmp(value_table[ctr], ptr1) != 0); ctr++); Xif (value_table[ctr] == NULL) { X rcerrmsg (filename, lineno, "invalid value", ptr1); X fputs ("\tvalue must be one of the following: ", stderr); X for (ctr = 0; value_table[ctr] != NULL; ctr++) { X fputc (' ', stderr); X fputs (value_table[ctr], stderr); X } X fputc ('\n', stderr); X return; X } X X/* make variable assignment */ X*variable = ctr; X} X X Xstatic void Xkeyfuncdef (filename, lineno, ptr1, keynum) Xint keynum, lineno; Xchar *filename, *ptr1; X{ Xint ctr; Xchar *ptr2; X X/* skip whitespace */ Xfor (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); X X/* find end of funcname */ Xfor (ptr2 = ptr1; (*ptr2 != '\n') && !isspace(*ptr2); *ptr2++); X*ptr2 = '\0'; X Xfor (ctr = 0; (funcname_table[ctr].kfunc != NULL) && (strcmp (ptr1, funcname_table[ctr].name) != 0); ctr++); Xif (funcname_table[ctr].kfunc == NULL) { X rcerrmsg (filename, lineno, "unknown function", ptr1); X } Xelse { X keytab[keynum].type = KEY_FUNC; X keytab[keynum].options = 0; X keytab[keynum].pntr = (voidptr) funcname_table[ctr].kfunc; X#ifdef DEBUG X fprintf (stderr, "keytab[%d] will call function %s\n", keynum, funcname_table[ctr].name); X#endif X } X} X X Xstatic void Xkeycmddef (filename, lineno, ptr1, keynum) Xint keynum, lineno; Xchar *filename, *ptr1; X{ Xint len, options, eolreached = 0; Xchar *ptr2; X X/* X * by default: X * 1. pause after the command finishes X * 2. don't append any filenames X * 3. don't verify command before executing it X */ Xoptions = OPT_WAIT; X X/* skip whitespace */ Xfor (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); Xif (*ptr1 == '\n') { X eolreached++; X } X Xwhile (!eolreached && (*ptr1 == '-')) { X /* find end of keyname */ X for (ptr2 = ptr1; (*ptr2 != '\n') && (*ptr2 != ' '); *ptr2++); X if (*ptr2 == '\n') { X eolreached++; X continue; X } X *ptr2 = '\0'; X X /* process option */ X if (strncmp (ptr1, "-tag", 4) == 0) { /* process all tagged files */ X options &= OPT_TAGCUR; X options |= OPT_TAGALL; X } X else if (strncmp (ptr1, "-cur", 4) == 0) { /* process only the current file */ X options &= OPT_TAGALL; X options |= OPT_TAGCUR; X } X else if (strncmp (ptr1, "-non", 4) == 0) { /* process no files */ X options &= OPT_TAGCUR; X options &= OPT_TAGALL; X } X else if (strncmp (ptr1, "-ver", 4) == 0) { /* verify command before executing */ X options |= OPT_VERIFY; X } X else if (strncmp (ptr1, "-nover", 6) == 0) { /* don't verify */ X options &= OPT_VERIFY; X } X else if (strncmp (ptr1, "-wait", 5) == 0) { /* wait after the command finished */ X options |= OPT_WAIT; X } X else if (strncmp (ptr1, "-nowait", 7) == 0) { /* don't wait after the command finished */ X options &= OPT_WAIT; X } X else { X rcerrmsg (filename, lineno, "unrecognized option", ptr1); X return; X } X X /* skip whitespace */ X ptr1 = ptr2; X for (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); X if (*ptr1 == '\n') { X eolreached++; X } X } X Xif (eolreached) { X rcerrmsg (filename, lineno, "missing command string", ""); X } Xelse { X keytab[keynum].type = KEY_CMD; X keytab[keynum].options = options; X len = strlen (ptr1) + 1; X ptr2 = (char *) malloc(len); X keytab[keynum].pntr = (voidptr) ptr2; X strcpy ((char *) keytab[keynum].pntr, ptr1); X for (; (*ptr2 != '\n') && (*ptr2 != '\0'); ptr2++); X *ptr2 = '\0'; /* change the newline to a null */ X#ifdef DEBUG X fprintf (stderr, "keytab[%d] will execute command %s (options=%o)\n", keynum, ptr1, options); X#endif X } X} X X Xstatic void Xkeydef (filename, lineno, ptr1) Xchar *filename, *ptr1; Xint lineno; X{ Xint keynum = 0, len, ctr1, eolreached = 0; Xchar *ptr2; X X/* skip whitespace */ Xfor (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); X X/* find end of keyname */ Xfor (ptr2 = ptr1; (*ptr2 != '\n') && (*ptr2 != ' '); *ptr2++); Xif (*ptr2 == '\n') { X rcerrmsg (filename, lineno, "missing key type", ""); X return; X } X*ptr2 = '\0'; X X/* validate keyname */ Xlen = strlen(ptr1); Xif (len == 1) { X keynum = *ptr1; /* just a single character */ X } Xelse if ((len >= 2) && (*ptr1 == '\\')) { /* character in decimal backslash notation */ X ptr1++; len--; X while (len > 0) { X keynum = (keynum * 10) + (*ptr1 - '0'); X ptr1++; len--; X } X } Xelse { X for (ctr1 = 0; (keydef_table[ctr1].name != NULL) && (strcmp (keydef_table[ctr1].name, ptr1) != 0); ctr1++); X if (keydef_table[ctr1].name == NULL) { X rcerrmsg (filename, lineno, "invalid keyname", ptr1); X return; X } X keynum = keydef_table[ctr1].value; X } X#ifdef DEBUG Xfprintf (stderr, "keynum value is %d\n", keynum); X#endif X X/* skip whitespace */ Xptr1 = ptr2; Xfor (ptr1++; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); X X/* find end of type */ Xfor (ptr2 = ptr1; (*ptr2 != '\n') && (*ptr2 != ' '); *ptr2++); Xif (*ptr2 == '\n') { X eolreached++; X } X*ptr2 = '\0'; X Xif (strncmp (ptr1, "func", 4) == 0) { /* builtin function */ X if (! eolreached) { X keyfuncdef (filename, lineno, ptr2, keynum); X } X else { X rcerrmsg (filename, lineno, "missing function name", ""); X } X } Xelse if (strncmp (ptr1, "cmd", 3) == 0) { /* command string */ X if (! eolreached) { X keycmddef (filename, lineno, ptr2, keynum); X } X else { X rcerrmsg (filename, lineno, "missing command string", ""); X } X } Xelse if (strncmp (ptr1, "undef", 5) == 0) { /* undefined */ X keytab[keynum].type = KEY_UNDEF; X keytab[keynum].options = 0; X keytab[keynum].pntr = (voidptr) NULL; X } Xelse { X rcerrmsg (filename, lineno, "invalid key type", ptr1); X } X} X X Xint Xreadrc (filename) Xchar *filename; X{ XFILE *fp; Xint eolreached, linectr = 0; Xchar line[1024], *ptr1, *ptr2; X Xif ((fp = fopen (filename, "r")) == NULL) { X if (errno != ENOENT) { X perror ("fopen"); X fprintf (stderr, "scan: cannot open initfile %s for input\n", filename); X sleep (5); X exit (1); X } X return; X } X Xwhile (fgets (line, 1024, fp) != NULL) { X linectr++; X eolreached = 0; X X /* skip over leading white space */ X for (ptr1 = line; (*ptr1 != '\n') && isspace(*ptr1); ptr1++); X if ((*ptr1 == '#') || (*ptr1 == '\n')) { X continue; /* ignore comment or empty lines */ X } X X /* find end of cmd */ X for (ptr2 = ptr1; (*ptr2 != '\n') && (*ptr2 != ' '); *ptr2++); X if (*ptr2 == '\n') { X eolreached++; X } X *ptr2 = '\0'; X X if (strncmp (ptr1, "key", 3) == 0) { /* key definition cmd */ X if (! eolreached) { X keydef (filename, linectr, ptr2); X } X else { X rcerrmsg (filename, linectr, "missing key name", ""); X } X } X X else if (strncmp (ptr1, "set", 3) == 0) { /* set option cmd */ X if (! eolreached) { X setoption (filename, linectr, ptr2); X } X else { X rcerrmsg (filename, linectr, "missing option name", ""); X } X } X X else { X rcerrmsg (filename, linectr, "unrecognized initfile command", ptr1); X } X } X Xfclose (fp); Xif (rcerrors) { X fprintf (stderr, "\r\n"); X exit (1); X } X} X X Xint Xwriterc () X{ Xstruct timeval tp; Xstruct timezone tzp; Xstruct tm *today; X XFILE *fp; Xint ctr, ctr2, *variable; Xchar **value_table; X Xif ((fp = fopen (rcfilename, "w")) == NULL) { X strcpy (errormsg, "count not open "); X strcat (errormsg, rcfilename); X strcat (errormsg, " file for writing "); X msgupdate (); X return; X } X Xgettimeofday (&tp, &tzp); Xtoday = localtime (&tp.tv_sec); Xfputs ("# Scan initialization file\n", fp); Xfprintf (fp, "# written by %s at %02d:%02d:%02d on %02d/%02d/%02d%02d\n", loginid, X today->tm_hour, today->tm_min, today->tm_sec, today->tm_mon + 1, today->tm_mday, X century, today->tm_year); X X/* write out options that are different from the default values */ Xfputs ("\n# options\n", fp); Xfor (ctr = 0; option_table[ctr].name != NULL; ctr++) { X if (*option_table[ctr].variable != option_table[ctr].default_value) { X variable = option_table[ctr].variable; X value_table = option_table[ctr].value_table; X fprintf (fp, "set %s %s\n", option_table[ctr].name, value_table[*variable]); X } X } X X/* write out key definitions that are different from the default values */ Xfputs ("\n# key definitions\n", fp); Xfor (ctr = 0; ctr < SIZEKEYTAB; ctr++) { X if ((keytab[ctr].type != default_keytab[ctr].type) X || (keytab[ctr].options != default_keytab[ctr].options) X || (keytab[ctr].pntr != default_keytab[ctr].pntr)) { X fputs ("key ", fp); X X /* print name of this key */ X for (ctr2 = 0; (keydef_table[ctr2].name != NULL) && (keydef_table[ctr2].value != ctr); ctr2++); X if (keydef_table[ctr2].name != NULL) { X fprintf (fp, "%s", keydef_table[ctr2].name); X } X else if ((ctr >= '!') && (ctr <= '~')) { X fprintf (fp, "%c", ctr); X } X else { X fprintf (fp, "\\%d", ctr); X } X X if (keytab[ctr].type == KEY_FUNC) { X X /* print name of this function */ X for (ctr2 = 0; (funcname_table[ctr2].name != NULL) X && (funcname_table[ctr2].kfunc != (Function *) keytab[ctr].pntr); ctr2++); X if (funcname_table[ctr2].name != NULL) { X fputs (" func ", fp); X fputs (funcname_table[ctr2].name, fp); X } X else { X fprintf (stderr, "writerc: key \\0%o is type KEY_FUNC, but the function cannot be found in the name table\n", ctr); X fputs (" undef", fp); X } X } X else if (keytab[ctr].type == KEY_CMD) { X fputs (" cmd ", fp); X if (keytab[ctr].options & OPT_VERIFY) { X fputs ("-verify ", fp); X } X if ((keytab[ctr].options & OPT_WAIT) == 0) { X fputs ("-nowait ", fp); X } X if (keytab[ctr].options & OPT_TAGALL) { X fputs ("-tag ", fp); X } X else if (keytab[ctr].options & OPT_TAGCUR) { X fputs ("-cur ", fp); X } X fputs ((char *) keytab[ctr].pntr, fp); X } X else { X fputs (" undef", fp); X } X fputc ('\n', fp); X } X } X Xfclose (fp); X} END_OF_FILE if test 12164 -ne `wc -c <'readrc.c'`; then echo shar: \"'readrc.c'\" unpacked with wrong size! fi # end of 'readrc.c' fi if test -f 'userfuncs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'userfuncs.c'\" else echo shar: Extracting \"'userfuncs.c'\" \(11698 characters\) sed "s/^X//" >'userfuncs.c' <<'END_OF_FILE' X/* X * This software is Copyright (c) 1989, 1990, 1991 by Patrick J. Wolfe. X * X * Permission is hereby granted to copy, distribute or otherwise X * use any part of this package as long as you do not try to make X * money from it or pretend that you wrote it. This copyright X * notice must be maintained in any copy made. X * X * Use of this software constitutes acceptance for use in an AS IS X * condition. There are NO warranties with regard to this software. X * In no event shall the author be liable for any damages whatsoever X * arising out of or in connection with the use or performance of this X * software. Any use of this software is at the user's own risk. X * X * If you make modifications to this software that you feel X * increases it usefulness for the rest of the community, please X * email the changes, enhancements, bug fixes as well as any and X * all ideas to me. This software is going to be maintained and X * enhanced as deemed necessary by the community. X * X * Patrick J. Wolfe X * uunet!uiucuxc!kailand!pwolfe X * pwolfe@kailand.kai.com X */ X X#include "config.h" X Xextern SIGTYPE die(); Xextern struct dblock cwd[MAXDIRSIZE]; Xextern int opt_pager_pause, opt_rm_prompt, topptr, curptr, lastptr; Xextern char *editor, *pager, *homedir, *shellpgm, prevdir[], errormsg[]; Xextern WINDOW *headwin, *datawin, *helpwin; X X X/* ---------------------------------------------------------------------------- */ X/* file processing user functions */ X/* ---------------------------------------------------------------------------- */ X X Xview_file (c) Xchar c; X{ Xint options = OPT_TAGCUR; X Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X if (opt_pager_pause) X options |= OPT_WAIT; X do_cmd (pager, options); X } X} X X Xview_tagged (c) Xchar c; X{ Xint options = OPT_TAGALL; X Xif (opt_pager_pause) X options |= OPT_WAIT; Xdo_cmd (pager, options); X} X X Xedit_file (c) Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X do_cmd (editor, OPT_TAGCUR); X } X} X X Xedit_tagged (c) Xchar c; X{ Xdo_cmd (editor, OPT_TAGALL); X} X X Xrm_file (c) Xchar c; X{ Xint options = OPT_TAGCUR | OPT_WAITERR; Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X if (opt_rm_prompt) { X options |= OPT_VERIFY; X } X if (cwd[curptr].type == S_IFDIR) X do_cmd ("rmdir", options); X else X do_cmd ("rm -f", options); X } X} X X Xrm_tagged (c) Xchar c; X{ Xint options = OPT_TAGALL | OPT_WAITERR; Xint ctr1, ctr2; X Xif (opt_rm_prompt) { X options |= OPT_VERIFY; X } X#ifdef RM_BREAKPOINT Xelse { /* if too many files are being deleted, verify anyway */ X for (ctr1 = ctr2 = 0; (ctr2 < RM_BREAKPOINT) && (ctr1 <= lastptr); ctr1++) { X if (cwd[ctr1].selected == 1) { X ctr2++; X } X } X if (ctr2 > RM_BREAKPOINT) { X options |= OPT_VERIFY; X } X } X#endif Xdo_cmd ("rm -f", options); X} X X Xexecute_file (c) /* this routine executes the current file and returns to scan */ Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X do_cmd (cwd[curptr].name, OPT_WAIT); X } X} X X Xexec_file (c2) /* this routine replaces scan with the current file */ Xchar c2; X{ Xint row = 2; Xchar c; X Xif (cwd[curptr].size == -1) { X beep (); X return; X } X X/* clear the screen, reset the terminal to normal mode, and run the command */ Xwmove (helpwin, 0, 0); Xwclrtobot (helpwin); Xwmove (datawin, 0, 0); Xwclrtobot (datawin); Xwmove (headwin, row, 0); Xwclrtobot (headwin); X X/* let the user know what we are doing */ Xmvwprintw (headwin, row, 0, "Execing the file: %s", cwd[curptr].name); X Xc = 'a'; Xwhile ((c != 'y') && (c != 'Y') && (c != 'N') && (c != 'n')) { X row++; X move (row, 0); X addstr ("Are you sure? "); X refresh (); X if ((c = my_getch (headwin)) == ERR) { X die (); X } X } Xif ((c != 'y') && (c != 'Y')) { X redraw_menu (); X return; X } X Xsignal (SIGHUP, SIG_DFL); /* trap signal 1, hangup */ Xsignal (SIGINT, SIG_DFL); /* trap signal 2, interrupt */ Xsignal (SIGQUIT, SIG_DFL); /* trap signal 3, quit */ Xsignal (SIGTERM, SIG_DFL); /* trap signal 15, software termination */ Xendwin (); X Xexeclp (cwd[curptr].name, cwd[curptr].name, 0); X Xperror ("execlp"); Xfprintf (stderr, "scan: execlp %s failed - returning to the scan program...", cwd[curptr].name); Xsleep (4); X Xinitscr (); /* initialize curses */ Xsignal (SIGHUP, die); /* trap signal 1, hangup */ Xsignal (SIGINT, die); /* trap signal 2, interrupt */ Xsignal (SIGQUIT, die); /* trap signal 3, quit */ Xsignal (SIGTERM, die); /* trap signal 15, software termination */ Xnoecho (); /* curses should not echo keys as they are typed */ Xnonl (); /* disable cr/lf mapping */ Xcrmode (); /* turn on cbreak mode */ Xheadwin = newwin (5, COLS, 0, 0); Xdatawin = newwin (PAGESIZE, COLS, 5, 0); Xhelpwin = newwin (1, COLS, 5 + PAGESIZE, 0); X#ifdef SYSVcurses Xidlok (datawin, TRUE); X#endif X Xredraw_menu (); X} X X Xcommand_file (c) Xchar c; X{ Xchar cmdline[256]; X Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X if (read_cmdline (helpwin, 0, 0, cmdline, COLS - 10, "command ? ") > 0) { X do_cmd (cmdline, OPT_TAGCUR | OPT_WAIT); X } X menu_update (); X redraw_help (); X } X} X X Xcommand_tagged (c) Xchar c; X{ Xchar cmdline[256]; X Xif (read_cmdline (helpwin, 0, 0, cmdline, COLS - 10, "command ? ") > 0) { X do_cmd (cmdline, OPT_TAGALL | OPT_WAIT); X } Xmenu_update (); Xredraw_help (); X} X X Xtoggle_tag (c) Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X cwd[curptr].selected = (cwd[curptr].selected * -1) + 1; X menu_update (); X } X} X X Xtag_all (c) Xchar c; X{ Xint ctr; X Xfor (ctr = 0; ctr <= lastptr; ctr++) { X if (cwd[ctr].size != -1) { X cwd[ctr].selected = 1; X } X } Xmenu_update (); X} X X Xuntag_all (c) Xchar c; X{ Xint ctr; X Xfor (ctr = 0; ctr <= lastptr; ctr++) { X cwd[ctr].selected = 0; X } Xmenu_update (); X} X X X/* ---------------------------------------------------------------------------- */ X/* change directory routines */ X/* ---------------------------------------------------------------------------- */ X X Xcd_prompt (c) Xchar c; X{ Xchar cmdline[256]; X Xif (read_cmdline (helpwin, 0, 0, cmdline, COLS - 4, "cd ") > 0) { X do_chdir (cmdline); X } Xelse { X menu_update (); X redraw_help (); X } X} X X X Xcd_file (c) Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X do_chdir (cwd[curptr].name); X } X} X X Xcd_or_edit (c) Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X if (cwd[curptr].type == S_IFDIR) { X do_chdir (cwd[curptr].name); X } X else { X edit_file (c); X } X } X} X X Xcd_or_view (c) Xchar c; X{ Xif (cwd[curptr].size == -1) { X beep (); X } Xelse { X if (cwd[curptr].type == S_IFDIR) { X do_chdir (cwd[curptr].name); X } X else { X view_file (c); X } X } X} X X Xcd_dot (c) Xchar c; X{ Xdo_chdir ("."); X} X X Xcd_dotdot (c) Xchar c; X{ Xdo_chdir (".."); X} X X Xcd_home (c) Xchar c; X{ Xdo_chdir (homedir); X} X X Xcd_back (c) Xchar c; X{ Xdo_chdir (prevdir); X} X X Xcd_root (c) Xchar c; X{ Xdo_chdir ("/"); X} X X X/* ---------------------------------------------------------------------------- */ X/* screen movement routines */ X/* ---------------------------------------------------------------------------- */ X X Xnext_line (c) Xchar c; X{ Xif (curptr >= lastptr) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "last page shown"); X msgupdate (); X } Xelse X menu_move (1); X} X X Xprev_line (c) Xchar c; X{ Xif (curptr <= 0) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "first page shown"); X msgupdate (); X } Xelse X menu_move (-1); X} X X Xtop_line (c) Xchar c; X{ Xif (curptr > topptr) X menu_move ((curptr - topptr) * -1); X} X X Xmiddle_line (c) Xchar c; X{ Xint midline; X Xmidline = lastptr - topptr; /* find line that is in the middle of the current screen */ Xif (midline > PAGESIZE) X midline = PAGESIZE; Xmidline = (midline / 2) + topptr; Xif (curptr > midline) X menu_move ((curptr - midline) * -1); Xelse if (curptr < midline) X menu_move (midline - curptr); X} X X Xbottom_line (c) Xchar c; X{ Xint newline; X Xnewline = topptr + PAGESIZE - 1; Xif (newline > lastptr) X newline = lastptr; Xif (curptr < newline) X menu_move (newline - curptr); X} X X Xnext_page (c) Xchar c; X{ Xif ((topptr >= (lastptr - PAGESIZE)) && (curptr < lastptr)) X menu_move (lastptr - curptr); Xelse if (topptr >= (lastptr - PAGESIZE)) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "last page shown"); X msgupdate (); X } Xelse X menu_scroll (PAGESIZE); X} X X Xnext_halfpage (c) Xchar c; X{ Xif ((topptr >= (lastptr - PAGESIZE)) && (curptr < lastptr)) X menu_move (lastptr - curptr); Xelse if (topptr >= (lastptr - PAGESIZE)) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "last page shown"); X msgupdate (); X } Xelse X menu_scroll (PAGESIZE / 2); X} X X Xprev_page (c) Xchar c; X{ Xif ((topptr <= 0) && (curptr > 0)) X menu_move (curptr * -1); Xelse if (topptr <= 0) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "first page shown"); X msgupdate (); X } Xelse X menu_scroll (PAGESIZE * -1); X} X X Xprev_halfpage (c) Xchar c; X{ Xif ((topptr <= 0) && (curptr > 0)) X menu_move (curptr * -1); Xelse if (topptr <= 0) { X if (lastptr < PAGESIZE) X strcpy (errormsg, "all files shown"); X else X strcpy (errormsg, "first page shown"); X msgupdate (); X } Xelse X menu_scroll ((PAGESIZE / 2) * -1); X} X X Xfirst_page (c) Xchar c; X{ Xtopptr = curptr = 0; Xmenu_update (); X} X X Xlast_page (c) Xchar c; X{ Xtopptr = (lastptr - PAGESIZE) + 1; Xif (topptr < 0) { X topptr = 0; X } Xcurptr = lastptr; Xmenu_update (); X} X X/* ---------------------------------------------------------------------------- */ X/* misc routines */ X/* ---------------------------------------------------------------------------- */ X X Xfork_shell (c) Xchar c; X{ Xdo_cmd (shellpgm, OPT_WAITERR); X} X X Xexit_pgm (c) Xchar c; X{ Xclear (); Xrefresh (); Xdie (); X} X X Xhelp_screen (c) Xchar c; X{ Xint i, row = 0; X Xwmove (headwin, 3, 0); Xwclrtobot (headwin); Xmvwaddstr (headwin, 3, 15, PGM_VERSION); Xwaddstr (headwin, " Help Screen"); Xwmove (headwin, 4, 0); Xfor (i = 1; i < COLS; i += 10) { X waddstr (headwin, "----------"); X } Xwrefresh (headwin); X Xwmove (datawin, row, 0); Xwclrtobot (datawin); Xmvwaddstr (datawin, row++, 0, "^F,^B,^D,^U - scroll through the menu"); Xmvwaddstr (datawin, row++, 0, "up,dn arrows - move current file pointer up or down through the file menu"); Xmvwaddstr (datawin, row++, 0, "g,G - move to first or last page of the file menu"); Xmvwaddstr (datawin, row++, 0, "H,M,L - move to top, middle, bottom file on the current page"); Xmvwaddstr (datawin, row++, 0, "d,u,b,~,/ - cd down,up,previous dir,home,root"); Xmvwaddstr (datawin, row++, 0, "c - prompt for directory name and cd to it"); Xmvwaddstr (datawin, row++, 0, ". - cd ., re-reads the current directory"); Xmvwaddstr (datawin, row++, 0, "Return - if pointing at a file, edit it, or if a dir, cd to it"); Xmvwaddstr (datawin, row++, 0, "m - toggle tagged status of the current file"); Xmvwaddstr (datawin, row++, 0, "T,U - tag, untag all files"); Xmvwaddstr (datawin, row++, 0, "e, r, v - edit, remove, view the current file"); Xmvwaddstr (datawin, row++, 0, "E, R, V - edit, remove, view all tagged files"); Xmvwaddstr (datawin, row++, 0, "x,X - prompt for cmd and execute passing current or tagged file(s)"); Xmvwaddstr (datawin, row++, 0, "!,% - spawn a subshell in the current directory"); Xmvwaddstr (datawin, row++, 0, "^L,^R - repaint the screen"); Xmvwaddstr (datawin, row++, 0, "S - enter SETUP mode, for defining keys or changing options"); Xmvwaddstr (datawin, row, 0, "q,Q - exit the SCAN program"); Xwrefresh (datawin); X Xwmove (helpwin, 0, 0); Xwstandout (helpwin); Xwaddstr (helpwin, "-------- Press any key to return to the previous menu ----------"); Xwstandend (helpwin); Xwrefresh (helpwin); X Xmy_getch (headwin); Xredraw_menu (); X} END_OF_FILE if test 11698 -ne `wc -c <'userfuncs.c'`; then echo shar: \"'userfuncs.c'\" unpacked with wrong size! fi # end of 'userfuncs.c' fi echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.