rsalz@bbn.com (Rich Salz) (03/16/89)
Submitted-by: Dan Heller <island!argv@sun.com> Posting-number: Volume 18, Issue 26 Archive-name: mush6.4/part04 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 19)." # Contents: dates.c help.c macros.c main.c main_panel.c options.c # Wrapped by rsalz@papaya.bbn.com on Mon Mar 13 19:25:09 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'dates.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dates.c'\" else echo shar: Extracting \"'dates.c'\" \(8311 characters\) sed "s/^X//" >'dates.c' <<'END_OF_FILE' X/* @(#)dates.c 1.1 (c) copyright 10/15/86 (Dan Heller) */ X X#include "mush.h" X X/* X * %02d%02d%02d%02d%02d%s yy mm dd hh mm weekday X * The standard "date format" stored in the msg data structure. X */ Xchar *day_names[] = { X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" X}; Xchar *month_names[] = { /* imported in pick.c */ X "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" X}; X X/* Time() returns a string according to criteria: X * if "now" is 0, then the current time is gotten and used. X * else, use the time described by now X * opts points to a string of args which is parsed until an unknown X * arg is found and opts will point to that upon return. X * valid args are T (time of day), D (day of week), M (month), Y (year), X * N (number of day in month -- couldn't think of a better letter). X */ Xchar * XTime(opts, now) Xregister char *opts; Xlong now; X{ X static char time_buf[30]; X struct tm *T; X register char *p = time_buf; X long x; X X if (!opts) X return NULL; X if (now) X x = now; X else X (void) time(&x); X T = localtime(&x); X for (;; opts++) { X switch(*opts) { X case 'T': X if (ison(glob_flags, MIL_TIME)) X (void) sprintf(p, "%2d:%02d", T->tm_hour, T->tm_min); X else X (void) sprintf(p, "%d:%02d", (T->tm_hour) ? X ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) : X 12, T->tm_min); X when 'D': case 'W': (void) strcpy(p, day_names[T->tm_wday]); X when 'M': (void) strcpy(p, month_names[T->tm_mon]); X when 'y': (void) sprintf(p, "%d", T->tm_year); X when 'Y': (void) sprintf(p, "19%d", T->tm_year); X when 'N': (void) sprintf(p, "%d", T->tm_mday); X otherwise: *--p = 0; return time_buf; X } X p += strlen(p); X *p++ = ' '; X } X} X X/* parse date and return a string that looks like X * "%2d%2d%2d%2d%2d%3c", wkday,yr,mo,date,hrs,mins X * This function is a bunch of scanfs on known date formats. Don't X * trust the "weekday" name fields because they may not be spelled X * right, or have the correct punctuation. Figure it out once the X * year and month and date have been determined. X */ Xchar * Xparse_date(p) Xregister char *p; X{ X /* When scanf-ing if month isn't a month, it could be a _long_ string. X * this is also the static buffer whose address we return. X */ X static char month[64]; X char Wkday[4]; X int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1; X X skipspaces(0); X X /* Possible combinations that we could have: X * day_number month_name year_number time timezone ... X * day_name month_name day_number time year_number X * day_name month_name day_number year_number time X * day_name day_number month_name year_number time X * day_number month_name year_number time X * day_number month_name year_number time-timezone (day) X * ^no colon separator X * day_name month_name day_number time timezone year_number X * day_number-month_name-year time X * day_name, day_number-month_name-year time X * day_number month_name year_number, time "-" X */ X /* programmer's note -- there are too many scanfs here for some compilers X * to put them all into one if statement. Use goto's :-( X */ X if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5) X goto gotit; X if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5) X goto gotit; X if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5) X goto gotit; X if (sscanf(p, "%*s %d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5) X goto gotit; X if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5) X goto gotit; X if (sscanf(p, "%d %s %d %2d%2d", &Day,month,&Year,&Hours,&Mins) == 5) X goto gotit; X if (sscanf(p, "%*s %s %d %d:%d:%*d %*s %d", X month, &Day, &Hours, &Mins, &Year) == 5) X goto gotit; X if (sscanf(p, "%*s %s %d %d:%d %*s %d", X month, &Day, &Hours, &Mins, &Year) == 5) X goto gotit; X if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5) X goto gotit; X if (sscanf(p,"%d %s %d, %d:%d:%*d -",&Day, month, &Year, &Hours, &Mins)== 5) X goto gotit; X if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",&Day, month, &Year, &Hours, &Mins)== 5) X goto gotit; X goto didnt_getit; Xgotit: X if (Year > 99) X Year %= 100; X if ((Month = month_to_n(month)) == -1) { X print("bad month: %s\n", p); X return NULL; X } X { X static int mtbl[]={0,31,59,90,120,151,181,212,243,273,304,334}; X int days_ctr; X X days_ctr = ((Year * 365) + ((Year + 3) / 4) + mtbl[Month-1] + Day + 6); X if (Month > 2 && (Year % 4 == 0)) X days_ctr++; X (void) (sprintf(Wkday, "%.3s", day_names[days_ctr % 7])); X } X return sprintf(month, "%02d%02d%02d%02d%02d%s", X Year, Month, Day, Hours, Mins, Wkday); Xdidnt_getit: X if (ison(glob_flags, WARNING)) X print("Unknown date format: %s\n", p); X return NULL; X} X X/* pass a string in the standard date format, put into string. X * return values in buffers provided they are not null. X */ Xchar * Xdate_to_string(Date, Yr, Mon, Day, Wkday, Tm, ret_buf) Xchar *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *ret_buf; X{ X unsigned int days_ctr; X int yr, mon, day, hr, mins; X char a_or_p, *p = ret_buf; X X (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c", X &yr, &mon, &day, &hr, &mins, Wkday); X Wkday[3] = 0; X a_or_p = (hr < 12)? 'a': 'p'; X X (void) sprintf(Yr, "19%d", yr); X (void) sprintf(Day, "%d", day); X (void) strcpy(Mon, month_names[mon-1]); X p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day)); X if (ison(glob_flags, MIL_TIME)) X (void) sprintf(p, "%2d:%02d",hr,mins); X else X (void) sprintf(p, "%2.d:%02d%cm", X (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p); X (void) strcpy(Tm, p); X return ret_buf; X} X X/* pass a string in the internal mush date format. X * return pointer to static buffer holding ctime-format date. X */ Xchar * Xdate_to_ctime(Date) Xchar *Date; X{ X static char ret_buf[32]; X char Wkday[4]; X int yr, mon, day, hr, mins; X X (void) sscanf(Date, "%2d%2d%2d%2d%2d%3c", X &yr, &mon, &day, &hr, &mins, Wkday); X X (void) sprintf(ret_buf, "%.3s %.3s %2.d %02d:%02d:00 19%d\n", X Wkday, month_names[mon-1], day, hr, mins, yr); X X return ret_buf; X} X X/* X * Build a date string according to the specification in the RFC for Date: X */ Xchar * Xrfc_date(buf) Xchar buf[]; X{ X struct tm *T; X#ifdef SYSV X long x; X extern char *tzname[]; X char *tz; X X (void) time(&x); X T = localtime(&x); X tz = tzname[T->tm_isdst]; X#else /* SYSV */ X#ifdef BSD X extern char *timezone(); X struct timeval mytime; X struct timezone myzone; X char *tz; X X (void) gettimeofday(&mytime, &myzone); X T = localtime(&mytime.tv_sec); X tz = timezone(myzone.tz_minuteswest, (T->tm_isdst && myzone.tz_dsttime)); X#else X char *tz = ""; X#endif /* BSD */ X#endif /* !SYSV */ X X return sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s", X day_names[T->tm_wday], /* day name */ X T->tm_mday, /* day of the month */ X month_names[T->tm_mon], /* month name */ X T->tm_year, /* year number */ X T->tm_hour, /* hours (24hr) */ X T->tm_min, T->tm_sec, /* mins/secs */ X tz); /* timezone */ X} X X#define JAN 1 X#define FEB 2 X#define MAR 3 X#define APR 4 X#define MAY 5 X#define JUN 6 X#define JUL 7 X#define AUG 8 X#define SEP 9 X#define OCT 10 X#define NOV 11 X#define DEC 12 X X/* stolen direct from ELM */ Xmonth_to_n(name) Xregister char *name; X{ X /** return the month number given the month name... **/ X X register char ch; X X switch (lower(*name)) { X case 'a' : if ((ch = lower(name[1])) == 'p') X return(APR); X else if (ch == 'u') X return(AUG); X else return(-1); /* error! */ X case 'd' : return(DEC); X case 'f' : return(FEB); X case 'j' : if ((ch = lower(name[1])) == 'a') X return(JAN); X else if (ch == 'u') { X if ((ch = lower(name[2])) == 'n') X return(JUN); X else if (ch == 'l') X return(JUL); X else return(-1); /* error! */ X } X else return(-1); /* error */ X case 'm' : if ((ch = lower(name[2])) == 'r') X return(MAR); X else if (ch == 'y') X return(MAY); X else return(-1); /* error! */ X case 'n' : return(NOV); X case 'o' : return(OCT); X case 's' : return(SEP); X default : return(-1); X } X} END_OF_FILE if test 8311 -ne `wc -c <'dates.c'`; then echo shar: \"'dates.c'\" unpacked with wrong size! fi # end of 'dates.c' fi if test -f 'help.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'help.c'\" else echo shar: Extracting \"'help.c'\" \(9302 characters\) sed "s/^X//" >'help.c' <<'END_OF_FILE' X/* @(#)help.c (c) copyright 10/15/86 (Dan Heller) */ X X/* X * This file contains two main routines: X * display_help() and find_help() X * Both are virtually equivalent in functionality; they are passed X * a char * or a char **. If a char * is passed, then open "file" X * argument (containing help strings) and search for %str% and read X * the following text until %% or EOF into a local buffer. X * If str is a char **, then that array of strings is used directly. X * X * If display_help is used, then the final array of strings used is X * displayed in the center of the bitmapped console in a box with X * shading and the user must hit the left mouse button to remove the X * message. the fd passed is the fd of the window locking the screen. X * X * In text mode, the routine find_help is used (or, if the graphics X * mode doesn't want to lock the screen to display a message). The X * same actions occur, but instead of "ifdef"ing up one function, I X * just made two for readability. X */ X#include <stdio.h> X#include "strings.h" X X#define NULL_FILE (FILE *)0 X X#ifdef SUNTOOL X#include <suntool/tool_hs.h> X#include <signal.h> X#include <suntool/fullscreen.h> X X#define l_width() font->pf_defaultsize.x /* width of letter */ X#define l_height() font->pf_defaultsize.y /* height of letter */ X X#define draw(win,x1,y1,x2,y2,OP) pw_vector(win, x1,y1,x2,y2,OP,1) X#define box(win, x1,y1,x2,y2,OP) \ X draw(win,x1,y1, x1,y2, OP), \ X draw(win,x1,y2, x2,y2, OP), \ X draw(win,x2,y2, x2,y1, OP), \ X draw(win,x2,y1, x1,y1, OP) X X#define DEF_CONT_MSG "Click LEFT mouse Button to continue." XDEFINE_CURSOR(oldcursor, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); X X/* shading */ Xstatic short dat_shade_25[] = { X#include <images/square_25.pr> X}; X Xstatic short dat_shade_50[] = { X#include <images/square_50.pr> X}; X Xstatic short dat_shade_75[] = { X#include <images/square_75.pr> X}; X Xstatic short dat_mouse_left[] = { X#include <images/confirm_left.pr> X}; X Xmpr_static(shade_25, 16, 16, 1, dat_shade_25); Xmpr_static(shade_50, 16, 16, 1, dat_shade_50); Xmpr_static(shade_75, 16, 16, 1, dat_shade_75); Xmpr_static(confirm_pr, 16, 16, 1, dat_mouse_left); X Xstatic struct cursor confirm_cursor = { 3, 3, PIX_SRC, &confirm_pr }; Xstatic struct pixrect *shading; X X#else X X#include <sys/types.h> X#define wprint printf X#define print printf X#define TRUE 1 X#define FALSE 0 X X#endif /* SUNTOOL */ X X/* what to print if nothing was found */ Xstatic char *def_msg[] = { X "There is no help found for \"%s\".", X "Perhaps getting help from another item", X "would be of some use.", 0 X}; X X#define MAXLINES 40 X#define MAXLENGTH 128 X X#ifdef SUNTOOL Xdisplay_help(fd, str, file, font) Xregister caddr_t *str; /* could be a single or double pointer */ Xregister char *file; Xregister struct pixfont *font; X{ X struct fullscreen *fs; X struct inputmask im, old_im; X struct inputevent event; X struct rect rect; X register char *p; X register int x, y, z, height; X struct pixrect *saved, *save_bits(); X int width = 0, old_link; X char *cont_msg = DEF_CONT_MSG, *getenv(); X char args[MAXLINES][MAXLENGTH], help_str[40]; X FILE *fp; X X if (!shading) X if (p = getenv("SHADE")) { X register int x = atoi(p); X if (x <= 25) X shading = &shade_25; X else if (x <= 50) X shading = &shade_50; X else X shading = &shade_75; X } else X shading = &shade_25; X X /* If no file given, take "str" arg as message to print */ X if (!file || !*file) { X for (height = 0; *str && height < MAXLINES-1; height++) { X if (!compose_str(*str, &width)) X break; X (void) strcpy(args[height], *str++); X } X } else { X if (!(fp = fopen(file, "r"))) X return -1; X /* look for %str% in helpfile */ X (void) sprintf(help_str, "%%%s%%\n", str); X X while(p = fgets(args[0], MAXLENGTH, fp)) X if (*p == '%' && !strcmp(p, help_str)) X break; X X if (!p || !fgets(args[0], MAXLENGTH, fp)) { X char buf[64]; X for(height = 0; def_msg[height] && height < MAXLINES-1; height++) { X sprintf(buf, def_msg[height], str); X compose_str(buf, &width); X (void) strcpy(args[height], buf); X } X } else X for (height = 0; p && *p && strcmp(p, "%%\n"); height++) { X compose_str(p, &width); X p = fgets(args[height+1], MAXLENGTH, fp); X } X } X if (height == MAXLINES - 1) X print("Help message is too long!\n"); X X fclose(fp); X X fs = fullscreen_init(fd); X /* Figure out the height and width in pixels (rect.r_height, rect.r_width) X * Remember to provide for the "confirm" line (cont_msg). X * extend the new box by 15 pixels on the sides (30 total), top, and bottom. X * finally, add 16 pixels for "shadow" -- remove before clearing area X * to preserve background and give a shadow-like appearance. X */ X if ((x = strlen(cont_msg)) > width) X width = x; /* this x value must be saved! */ X rect.r_width = (width*l_width()) + 30 + 16; X rect.r_height = ((height+1) * l_height()) + 30 + 16; X rect.r_left = fs->fs_screenrect.r_left + X (fs->fs_screenrect.r_width / 2) - (rect.r_width / 2); X rect.r_top = fs->fs_screenrect.r_top + X (fs->fs_screenrect.r_height / 2) - (rect.r_height / 2); X X /* save old area */ X saved = save_bits(fs->fs_pixwin, &rect); X X /* prepare surface, clear the background, and reset rect for shadow */ X pw_preparesurface(fs->fs_pixwin, &rect); X pw_lock(fs->fs_pixwin, &rect); X rect.r_width -= 16; X rect.r_height -= 16; X X pw_writebackground(fs->fs_pixwin, X rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_CLR); X X /* make a box that's 5 pixels thick. Then add a thin box inside it */ X for (z = 0; z < 5; z++) X box(fs->fs_pixwin, X rect.r_left+z, rect.r_top+z, X rect.r_left+rect.r_width-z-1, rect.r_top+rect.r_height-z-1, X PIX_SRC); X box(fs->fs_pixwin, X rect.r_left+z+2, rect.r_top+z+2, X rect.r_left+rect.r_width-z-3, rect.r_top+rect.r_height-z-3, X PIX_SRC); X X /* shading -- pw_replrop() doesn't work (bug) X * NOTE: fs->fs_screenrect.r_top and r_left are negative values X */ X pr_replrop(fs->fs_pixwin->pw_pixrect, X rect.r_left + rect.r_width - fs->fs_screenrect.r_left, X rect.r_top + 16 - fs->fs_screenrect.r_top, X 16, rect.r_height-16, PIX_SRC|PIX_DST, shading, 0, 0); X pr_replrop(fs->fs_pixwin->pw_pixrect, X rect.r_left + 16 - fs->fs_screenrect.r_left, X rect.r_top+rect.r_height - fs->fs_screenrect.r_top, X rect.r_width, 16, PIX_SRC|PIX_DST, shading, 0, 0); X X if (x > width) X x = 15; X else X x = rect.r_width/2 - (x*l_width())/2; X y = rect.r_height - 15; X X /* Print everything in reverse order now; start with the "confirm" string X * (which is centered and highlighted) X */ X pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, PIX_SRC,font, cont_msg); X pw_text(fs->fs_pixwin, rect.r_left+x+1, rect.r_top+y, PIX_SRC|PIX_DST, font, X cont_msg); X X y -= (5 + l_height()); X x = 15; X X /* now print each string in reverse order (start at bottom of box) */ X for (height--; height >= 0; height--) { X pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, X PIX_SRC, font, args[height]); X y -= l_height(); X } X X pw_unlock(fs->fs_pixwin); X X /* wait for user to read and confirm */ X win_getinputmask(fd, &old_im, &old_link); X input_imnull(&im); X im.im_flags |= IM_ASCII; X win_setinputcodebit(&im, MS_LEFT); X win_setinputcodebit(&im, MS_MIDDLE); X win_setinputcodebit(&im, MS_RIGHT); X win_setinputmask(fd, &im, &im, WIN_NULLLINK); X win_getcursor(fd, &oldcursor); X win_setcursor(fd, &confirm_cursor); X while (input_readevent(fd, &event) != -1 && event.ie_code != MS_LEFT); X X /* restore old cursor */ X win_setcursor(fd, &oldcursor); X X /* restore old pixrect (size already restored) */ X rect.r_height += 16; /* to take care of the shadow */ X rect.r_width += 16; X restore_bits(fs->fs_pixwin, &rect, saved); X /* release screen */ X fullscreen_destroy(fs); X win_setinputmask(fd, &old_im, &old_im, old_link); X return 0; X} X Xstatic Xcompose_str(p, width) Xregister char *p; Xint *width; X{ X register int x; X if (!p || !*p) X return 0; X x = strlen(p); X if (p[x-1] == '\n') X p[--x] = 0; /* get rid of newline */ X if (x > *width) X *width = x; X return 1; X} X#endif /* SUNTOOL */ X Xfind_help(str, file) Xregister caddr_t *str; Xregister char *file; X{ X register char *p; X char buf[BUFSIZ], help_str[40]; X register int height; X extern char *no_newln(); X FILE *fp; X X /* If no file given, take "str" arg as message to print */ X if (!file || !*file) { X /* use the pager on the args to the function */ X do_pager(NULL, TRUE); X while (*str) { X (void) do_pager(*str++, FALSE); X if (do_pager("\n", FALSE) == EOF) X break; X } X do_pager(NULL, FALSE); X return 0; X } X X if (!(fp = fopen(file, "r"))) X return -1; X /* look for %str% in helpfile */ X (void) sprintf(help_str, "%%%s%%\n", str); X X while (p = fgets(buf, sizeof buf, fp)) X if (*p == '%' && !strcmp(p, help_str)) X break; X if (!p) X /* Didn't find the help requested */ X for (height = 0; def_msg[height]; height++) { X wprint(def_msg[height], str); X wprint("\n"); X } X else { X do_pager(NULL, TRUE); X while ((p = fgets(buf, sizeof buf, fp)) && strcmp(p, "%%\n")) X if (do_pager(buf, FALSE) == EOF) X break; X do_pager(NULL, FALSE); X } X fclose(fp); X X return 0; X} END_OF_FILE if test 9302 -ne `wc -c <'help.c'`; then echo shar: \"'help.c'\" unpacked with wrong size! fi # end of 'help.c' fi if test -f 'macros.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'macros.c'\" else echo shar: Extracting \"'macros.c'\" \(8623 characters\) sed "s/^X//" >'macros.c' <<'END_OF_FILE' X/* (@)# macros.c (c) copyright 9/19/88 (Bart Schaefer, Dan Heller) */ X X#include "bindings.h" X#include "mush.h" X Xextern struct cmd_map map_func_names[]; X Xstruct cmd_map *mac_stack, *mac_hide; X Xextern char *calloc(); X X/* X * print current binding to macro mappings if "str" is NULL. X * else return the string "x_str" which the str is bound to. X */ Xchar * Xc_macro(name, str, opts) Xchar *name; Xregister char *str; Xregister struct cmd_map *opts; X{ X register int incurses = iscurses; X char buf[MAX_MACRO_LEN], buf2[sizeof buf * 3]; X X if (!str) { X for (; opts; opts = opts->m_next) X if (opts->m_cmd == C_MACRO) X break; X if (!opts) { X print("No %s settings.\n", name); X return (char *)(-1); X } X if (incurses) X clr_bot_line(), iscurses = FALSE; X (void) do_pager(NULL, TRUE); X (void) do_pager(sprintf(buf, "\nCurrent %s settings:\n\n",name), FALSE); X } X X if (!opts) X return NULL; X X for (; opts; opts = opts->m_next) { X if (opts->m_cmd != C_MACRO) X continue; X if (!str) { X (void) do_pager(sprintf(buf, "%-20.20s ", X ctrl_strcpy(buf2, opts->m_str, FALSE)), FALSE); X if (do_pager(sprintf(buf, "%s\n", X ctrl_strcpy(buf2, opts->x_str, TRUE)), FALSE) == EOF) X break; X } else { X if (strcmp(str, opts->m_str)) X continue; X else X return opts->x_str; X } X } X iscurses = incurses; X if (str) X (void) do_pager(NULL, FALSE); X return NULL; X} X Xmac_push(str) Xregister char *str; X{ X register struct cmd_map *tmp; X X /* now make a new macro struct and set fields */ X if (!(tmp = (struct cmd_map *)calloc((unsigned)1,sizeof(struct cmd_map)))) { X error("calloc"); X return -1; X } X tmp->m_next = mac_stack; X mac_stack = tmp; X tmp->x_str = savestr(str); /* x_str is the text of the expansion */ X tmp->m_str = tmp->x_str; /* m_str is the current read position */ X X /* X * Save the current state of the glob_flags so X * mac_push() can also serve as unget of stdin X */ X tmp->m_cmd = glob_flags; X return 0; X} X Xvoid Xmac_pop() X{ X register struct cmd_map *tmp; X X if (mac_stack) { X tmp = mac_stack; X mac_stack = tmp->m_next; X xfree(tmp->x_str); X xfree(tmp); X } X /* X * Restore saved MACRO glob_flags only (see mac_push()) X */ X if (mac_stack) { X if (ison(mac_stack->m_cmd, IN_MACRO)) X turnon(glob_flags, IN_MACRO); X else X turnoff(glob_flags, IN_MACRO); X if (ison(mac_stack->m_cmd, LINE_MACRO)) X turnon(glob_flags, LINE_MACRO); X else X turnoff(glob_flags, LINE_MACRO); X if (ison(mac_stack->m_cmd, QUOTE_MACRO)) X turnon(glob_flags, QUOTE_MACRO); X else X turnoff(glob_flags, QUOTE_MACRO); X } X} X X/* Abandon macro processing */ Xvoid Xmac_flush() X{ X while (mac_stack) X mac_pop(); X if (mac_hide) { X mac_stack = mac_hide; X mac_hide = NULL_MAP; X while (mac_stack) X mac_pop(); X } X turnoff(glob_flags, IN_MACRO); X turnoff(glob_flags, LINE_MACRO); X turnoff(glob_flags, QUOTE_MACRO); X} X X/* Check for pending input from a macro. */ Xmac_pending() X{ X register struct cmd_map *msp; X X for (msp = mac_stack; msp && !*(msp->m_str); msp = msp->m_next) X ; X X return !!msp; X} X X/* Get input and treat it as a macro. */ Xget_mac_input(newline) Xint newline; /* 1 if newline to be appended, 0 otherwise */ X{ X register int len; X char buf[MAX_MACRO_LEN]; X X /* This call cannot be nested */ X if (mac_hide) X return -1; X X /* Hide the mac_stack so input comes from stdin */ X mac_hide = mac_stack; mac_stack = NULL_MAP; X X if ((len = Getstr(buf, MAX_MACRO_LEN - 1, 0)) < 0) X return len; X if (newline) { X buf[len++] = '\n'; X buf[len] = 0; X } X X /* Restore the mac_stack */ X if (mac_stack) { X /* X * Somehow, a push happened even though mac_hide was X * nonzero -- maybe by line wrap? Fix it as best we can. X */ X struct cmd_map *msp; X for (msp = mac_stack; msp->m_next; msp = msp->m_next) X ; X msp->m_next = mac_hide; X } else X mac_stack = mac_hide; X mac_hide = NULL_MAP; X X /* Restore saved flags */ X if (mac_stack) { X if (ison(mac_stack->m_cmd, IN_MACRO)) X turnon(glob_flags, IN_MACRO); X else X turnoff(glob_flags, IN_MACRO); X if (ison(mac_stack->m_cmd, LINE_MACRO)) X turnon(glob_flags, LINE_MACRO); X else X turnoff(glob_flags, LINE_MACRO); X } X if (len > 0) X Ungetstr(buf); X X return 1; X} X X/* getchar() substitute -- reads from the current macro if one is active, X * otherwise does a getchar(). X * X * NOTE: In the mac_stack, x_str is the saved text of the current macro, X * and m_str is the current read position within the macro. X */ Xm_getchar() X{ X register char c; X X while (mac_stack && (! *(mac_stack->m_str))) X mac_pop(); X if (mac_stack) { X c = *((mac_stack->m_str)++); X return c; X } else { X turnoff(glob_flags, IN_MACRO); X turnoff(glob_flags, LINE_MACRO); X turnoff(glob_flags, QUOTE_MACRO); X while ((c = getchar()) == 0) /* Ignore NUL chars from stdin */ X ; /* until better solution found */ X return c; X } X} X Xm_ungetc(c) Xregister char c; X{ X if (mac_stack && (mac_stack->m_str > mac_stack->x_str)) X *(--(mac_stack->m_str)) = c; X else X (void) ungetc(c, stdin); X} X X/* X * Try to read a long command; assumes MAC_LONG_CMD already seen. X * On immediate failure, return 0. X * On failure after reading some input, return less than zero. X * On success, return greater than 0. X * The absolute value of the return is the number of chars placed in buf. X */ Xread_long_cmd (buf) Xchar *buf; X{ X register char c, *p = buf; X register int count = 0; X X /* X * Test in_macro() in this loop because the _entire_ X * long command _must_ be in the macro -- if we run X * out of macro in mid-long-command, it is an error. X */ X while (in_macro() && (count < MAX_LONG_CMD - 1) X && ((c = m_getchar()) != MAC_LONG_END)) { X *p++ = c; ++count; X } X *p = '\0'; X if (c != MAC_LONG_END) X return (-count); X return count; X} X X/* X * Identify and possibly execute a reserved long macro command X * Executes if do_exec is true. Otherwise, just parse. X */ Xreserved_cmd (buf, do_exec) Xchar *buf; X{ X int ret = 1; X X if (!strcmp(buf, MAC_GET_STR)) { X if (do_exec) X ret = get_mac_input(0); X } else if (!strcmp(buf, MAC_GET_LINE)) { X if (do_exec) X ret = get_mac_input(1); X } else X ret = 0; X return ret; X} X X#ifdef CURSES X X/* X * Identify (and possibly execute, if reserved) curses mode commands X * that appear in macro strings enclosed by MAC_LONG_CMD and X * MAC_LONG_END. Return the binding of the command. X */ Xlong_mac_cmd (c, do_exec) Xint c; X{ X char buf[MAX_LONG_CMD]; X register int count, binding; X int y, x; X X if (c != MAC_LONG_CMD) X return C_ERROR; X X if ((count = read_long_cmd(buf)) <= 0) { X print("Invalid long macro command"); X if (ison(glob_flags, CNTD_CMD)) X putchar('\n'); X if (do_exec) X mac_flush(); X return C_ERROR; X } X X if (do_exec) { X if (ison(glob_flags, CNTD_CMD)) X clr_bot_line(); X getyx(stdscr, y, x); X move(LINES - 1, 0); X } X if (reserved_cmd(buf, do_exec)) { X if (do_exec) { X if (isoff(glob_flags, CNTD_CMD)) X move(y, x); X return getcmd(); X } else X return C_NULL; X } else if (do_exec) X move(y, x); X X /* Can start at C_NULL because of "no-op" command */ X for (count = 0; count <= C_HELP; count++) { X if (!strcmp(buf, map_func_names[count].m_str)) { X binding = (int)map_func_names[count].m_cmd; X break; X } X } X /* Don't allow C_MACRO to be called directly */ X if (count > C_HELP || binding == C_MACRO) { X print("Invalid long macro command"); X if (ison(glob_flags, CNTD_CMD)) X putchar('\n'); X return C_ERROR; X } else X return binding; X} X X#endif /* CURSES */ X X/* X * Check the validity of a macro binding as far as possible X */ Xcheck_mac_bindings(buf) Xchar *buf; X{ X int ok = TRUE; X X while (ok && buf && *buf) { X if (*buf == MAC_LONG_CMD) { X char *i; X#ifdef CURSES X int count; X#endif /* CURSES */ X X if (ok) X ok = ((i = index(++buf, MAC_LONG_END)) != NULL); X if (i) X *i = '\0'; /* Don't worry, we'll fix it */ X else X return ok; X#ifdef CURSES X /* OK to start at C_NULL because of "no-op" command */ X for (count = 0; count <= C_HELP; count++) X if (! strcmp(buf, map_func_names[count].m_str)) X break; X /* Don't allow C_MACRO to be called directly */ X if (count == C_MACRO) X ok = FALSE; X else if (count > C_HELP) X#endif /* CURSES */ X if (ok && !(ok = reserved_cmd(buf, FALSE))) X wprint("Warning: unrecognized curses command: \"%s\"\n", buf); X buf = i; X *buf++ = MAC_LONG_END; X } else if (*buf++ == '\\' && *buf) X ++buf; X } X return ok; X} END_OF_FILE if test 8623 -ne `wc -c <'macros.c'`; then echo shar: \"'macros.c'\" unpacked with wrong size! fi # end of 'macros.c' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(8512 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X/* @(#)main.c (c) copyright 10/18/86 (Dan Heller) */ X X#include "mush.h" X#include "options.h" X X#define PATCHDATE "3/12/89" /* Here because EVERYTHING depends on mush.h */ X X#if defined(sun) && defined(M_DEBUG) Xcpu() X{ X print("CPU time limit exceeded!\n"); X} X#endif /* sun && DEBUG */ X X#ifdef LCKDFLDIR Xextern char *lckdfldir; X#endif /* LCKDFLDIR */ X X#ifdef DOT_LOCK Xint sgid; X#ifdef BSD Xint rgid; X#endif /* BSD */ X#endif /* DOT_LOCK */ X X/*ARGSUSED*/ /* we ignore envp */ Xmain(argc, argv) Xchar **argv; X{ X int n; X char buf[256]; X register char *p; X char **args; X struct mush_flags Flags; X X#ifdef LCKDFLDIR X lckdfldir = LCKDFLDIR; X#endif /* LCKDFLDIR */ X if (prog_name = rindex(*argv, '/')) X prog_name++; X else X prog_name = *argv; X X (void) signal(SIGBUS, bus_n_seg); X (void) signal(SIGSEGV, bus_n_seg); X (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */ X X#if defined(sun) && defined(M_DEBUG) X (void) signal(SIGXCPU, cpu); X X if (p = getenv("MALLOC_DEBUG")) X malloc_debug(atoi(p)); X else X malloc_debug(0); X#endif /* sun && debug */ X X if (!isatty(0)) X turnon(glob_flags, REDIRECT); X X n = 0; /* don't ignore no such file or directory */ X p = getpath(COMMAND_HELP, &n); X X if (n) X cmd_help = "cmd_help"; X else X strdup(cmd_help, p); X X init(); /* must be done before checking mail since "login" is set here */ X#ifdef HOMEMAIL X { X char *home = do_set(set_options, "home"); X if (!home) X home = ""; X strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE)); X } X#else /* HOMEMAIL */ X strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login)); X#endif /* HOMEMAIL */ X X args = DUBL_NULL; X n = preparse_opts(&argc,argv,&args); X X /* check for any mail at all and exit if we're not continuing */ X if (!n) { X struct stat statb; X if (stat(spoolfile, &statb) || statb.st_size == 0) { X printf("No mail for %s.\n", login); X exit(0); X } X } X X#ifdef DOT_LOCK X sgid = getegid(); X#ifdef BSD X rgid = getgid(); X setregid(sgid, rgid); X#else X setgid(getgid()); X#endif /* BSD */ X#endif /* DOT_LOCK */ X X parse_options(&argv, &Flags); X X if (Flags.source_rc) { X /* use cmd_line() in case DEFAULT_RC has expandable chars */ X (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list); X (void) source(0, DUBL_NULL); X } X if (*spoolfile != '/') { X n = 1; X p = getpath(spoolfile, &n); X if (n == -1) X fputs(p, stderr), exit(1); X else if (n) X fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1); X else X strdup(spoolfile, p); X } X X set_cwd(); /* call _after_ sourcing files */ X X#ifdef SUNTOOL X if (istool) X if (ison(glob_flags, REDIRECT)) X puts("You can't redirect input to a tool."), exit(1); X else X make_tool(args), turnon(glob_flags, DO_SHELL); X#endif /* SUNTOOL */ X X /* now we're ready for I/O */ X if (isoff(glob_flags, REDIRECT)) { X /* make sure we can always recover from no echo mode */ X (void) signal(SIGINT, catch); X (void) signal(SIGQUIT, catch); X (void) signal(SIGHUP, catch); X if (istool) X turnon(glob_flags, ECHO_FLAG); X tty_settings(); X#ifdef SIGCONT X (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */ X#endif /* SIGCONT */ X /* echo_off() checks to see if echo_flg is set, so don't worry */ X echo_off(); X } X X if (!istool && *argv) { /* we could check IS_SENDING */ X char recipients[BUFSIZ]; X (void) argv_to_string(recipients, argv); X fix_up_addr(recipients); X if (Flags.Cc && *(Flags.Cc)) X fix_up_addr(Flags.Cc); X if (Flags.Bcc && *(Flags.Bcc)) X fix_up_addr(Flags.Bcc); X /* prompt for subject and Cc list, but not "To: " X * mail_someone() already takes care of redirection. X * if -s or -c options are given, they will be passed. X */ X if (do_set(set_options, "ask")) X turnon(Flags.flg, NEW_SUBJECT); X if (do_set(set_options, "autosign")) X turnon(Flags.flg, SIGN); X if (do_set(set_options, "autoedit")) X turnon(Flags.flg, EDIT); X if (do_set(set_options, "verbose")) X turnon(Flags.flg, VERBOSE); X if (do_set(set_options, "fortune")) X turnon(Flags.flg, DO_FORTUNE); X /* set now in case user is not running shell, but is running debug */ X (void) signal(SIGCHLD, sigchldcatcher); X if (!setjmp(jmpbuf)) X (void) mail_someone(recipients, X Flags.Subj, X Flags.Cc, X Flags.Bcc, X Flags.flg, X NULL); X /* do shell set from above: "mush -S user" perhaps */ X if (isoff(glob_flags, DO_SHELL) && !*mailfile) { X if (isoff(glob_flags, REDIRECT)) X echo_on(); X exit(0); X } X } X turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */ X X if (ison(glob_flags, REDIRECT)) { X puts("You can't redirect input unless you're sending mail."); X puts("If you want to run a shell with redirection, use \"-i\""); X cleanup(0); X } X if (!*mailfile) { X strdup(mailfile, spoolfile); X if (!mail_size() && isoff(glob_flags, DO_SHELL)) { X /* we know it's not the spool file here */ X printf("No mail in %s.\n", mailfile); X echo_on(), exit(0); X } X } X X if (!hdrs_only) { X /* catch will test DO_SHELL and try to longjmp if set. this is a X * transition state from no-shell to do-shell to ignore sigs to X * avoid a longjmp botch. Note setjmp isn't called until do_loop(). X */ X turnon(glob_flags, IGN_SIGS); X#ifdef CURSES X if (ison(glob_flags, PRE_CURSES)) X (void) curses_init(0, DUBL_NULL); X turnoff(glob_flags, PRE_CURSES); X#endif /* CURSES */ X } X X /* find a free tmpfile */ X if (!(p = do_set(set_options, "tmpdir")) && X !(p = do_set(set_options, "home"))) Xalted: X p = ALTERNATE_HOME; X { X int pid = getpid(); X while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK)) X ; X } X /* just create the file, make sure it's empty. It'll close later and X * be reopened for reading only. X */ X if (!(tmpf = mask_fopen(tempfile, "w"))) { X if (strcmp(p, ALTERNATE_HOME)) X goto alted; X error("Can't create tempfile %s", tempfile); X cleanup(0); X } X X /* do pseudo-intelligent stuff with certain signals */ X (void) signal(SIGINT, catch); X (void) signal(SIGQUIT, catch); X (void) signal(SIGHUP, catch); X X if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) && X !do_set(set_options, "quiet")) X printf("%s: Type '?' for help.\n", VERSION); X X (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile); X if (argv = make_command(buf, TRPL_NULL, &argc)) { X if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) X turnoff(glob_flags, IGN_SIGS), cleanup(0); X#ifdef CURSES X if (iscurses) X (void) curses_help_msg(TRUE); X#endif /* CURSES */ X free_vec(argv); X } X X if (hdrs_only) { X (void) sprintf(buf, "headers %s", hdrs_only); X if (argv = make_command(buf, TRPL_NULL, &argc)) X (void) do_hdrs(argc, argv, NULL); X cleanup(0); X } X X turnon(glob_flags, DO_SHELL); X if (istool && msg_cnt) X set_isread(current_msg); X X /* finally, if the user wanted to source a file to execute, do it now */ X if (Flags.src_file) { X char *s_argv[2]; X s_argv[1] = Flags.src_file; X (void) source(2, s_argv); X if (!istool && Flags.src_n_exit) X cleanup(0); X } X X#ifdef SUNTOOL X if (istool) { X n = 0; X if (!tool_help) { X p = getpath(TOOL_HELP, &n); X if (n) { X fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p); X tool_help = "tool_help"; X } else X strdup(tool_help, p); X } X if (time_out < 30) X time_out = 60; X turnoff(glob_flags, IGN_SIGS); X (void) do_hdrs(0, DUBL_NULL, NULL); X timerclear(&(mail_timer.it_interval)); X timerclear(&(mail_timer.it_value)); X mail_timer.it_value.tv_sec = time_out; X setitimer(ITIMER_REAL, &mail_timer, NULL); X (void) signal(SIGALRM, check_new_mail); X unlock_cursors(); X while (!(tool->tl_flags & TOOL_DONE)) X tool_select(tool, 1); X cleanup(0); X } X#endif /* SUNTOOL */ X do_loop(); X} X Xdo_version() X{ X#ifdef PATCHDATE X print("%s [%s]\n", VERSION, PATCHDATE); X#else /* !PATCHDATE */ X print("%s\n", VERSION); X#endif /* PATCHDATE */ X return -1; X} X X/* set the current working directory */ Xset_cwd() X{ X char buf[MAXPATHLEN], cwd[MAXPATHLEN]; X#ifndef SYSV X extern char *getwd(); X#else /* SYSV */ X extern char *getcwd(); X#endif /* SYSV */ X X#ifndef SYSV X if (getwd(cwd) == NULL) X#else X if (getcwd(cwd, MAXPATHLEN) == NULL) X#endif /* SYSV */ X { X error("getcwd: %s", cwd); X (void) un_set(&set_options, "cwd"); X } else { X char *argv[4]; X argv[0] = "cwd"; X argv[1] = "="; X argv[2] = cwd; X argv[3] = NULL; X (void) add_option(&set_options, argv); X } X} END_OF_FILE if test 8512 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'main_panel.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main_panel.c'\" else echo shar: Extracting \"'main_panel.c'\" \(9189 characters\) sed "s/^X//" >'main_panel.c' <<'END_OF_FILE' X/* "@(#)main_panel.c (c) copyright 10/18/86 (Dan Heller) */ X X#include "mush.h" X Xmake_main_panel(choice_args, button_args) Xchar **choice_args, **button_args; X{ X /* main panel stuff: */ X panel_sw = panel_create(tool, X PANEL_HEIGHT, 80, X 0); X main_panel = (Panel)panel_sw->ts_data; X X quit_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 4, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Done", 6, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Done", X PANEL_CHOICE_STRINGS, "Close to Icon", X "Quit Tool", X "Help", X 0, X PANEL_NOTIFY_PROC, toolquit, X 0); X X help_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 79, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Help", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Available Help", X PANEL_CHOICE_STRINGS, "General", X "Help with \"help\"", X "The Mouse", X "Windows", X "Function Keys", X "Message headers", X "Message lists", X 0, X PANEL_NOTIFY_PROC, do_help, X 0); X X read_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 136, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Next", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Next Message", X PANEL_CHOICE_STRINGS, "Read Next", "Help", 0, X PANEL_NOTIFY_PROC, read_mail, X 0); X X respond_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 193, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Reply", 5, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Respond to Current Message", X PANEL_CHOICE_STRINGS, "Sender Only", X "Sender Only (include msg)", X "All Recipients", X "All Recipients (include msg)", X "Help", 0, X PANEL_NOTIFY_PROC, respond_mail, X 0); X X delete_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 259, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Delete", 6, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Delete/Undelete Messages", X PANEL_CHOICE_STRINGS, "Delete", X "Undelete", X "Help", 0, X PANEL_NOTIFY_PROC, delete_mail, X 0); X X sort_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 334, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Sort", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Sort Messages", X PANEL_CHOICE_STRINGS, "By Date", X "By Author", X "By Subject", X "By Subject (ignore Re:)", X "By Status", X "Help", 0, X PANEL_NOTIFY_PROC, do_sort, X 0); X X option_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 391, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Opts", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Mail Options", X PANEL_CHOICE_STRINGS, "Set Options", "Function keys", X "Help", 0, X PANEL_NOTIFY_PROC, p_set_opts, X 0); X X alias_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 448, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Aliases", 7, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Mail Aliases", X PANEL_CHOICE_STRINGS, "Current Aliases", X "Add/Change alias", X "Unalias", "Help", 0, X PANEL_NOTIFY_PROC, p_set_opts, X 0); X X comp_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 532, X PANEL_ITEM_Y, 4, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Compose", 8, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Compose a letter", X PANEL_CHOICE_STRINGS, "Help", 0, X PANEL_NOTIFY_PROC, do_compose, X 0); X X file_item = panel_create_item(main_panel, PANEL_TEXT, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 4, X PANEL_ITEM_Y, 30, X PANEL_LABEL_FONT, fonts[DEFAULT], X PANEL_SHOW_MENU, TRUE, X PANEL_LABEL_STRING, "filename:", X PANEL_MENU_CHOICE_STRINGS, "Save message without message header",0, X PANEL_VALUE_DISPLAY_LENGTH, 35, X PANEL_NOTIFY_STRING, "\n\r", X PANEL_NOTIFY_PROC, file_dir, X 0); X X input_item = panel_create_item(main_panel, PANEL_TEXT, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 373, X PANEL_ITEM_Y, 30, X PANEL_SHOW_ITEM, FALSE, X PANEL_SHOW_MENU, TRUE, X PANEL_LABEL_FONT, fonts[DEFAULT], X PANEL_VALUE_DISPLAY_LENGTH, 20, X PANEL_NOTIFY_STRING, "\n\r", X PANEL_NOTIFY_PROC, text_done, X 0); X X print_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 4, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Printer", 7, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Printing Messages", X PANEL_CHOICE_STRINGS, "Help", 0, X PANEL_NOTIFY_PROC, do_lpr, X 0); X X folder_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 88, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "folder", 6, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Change folder", X PANEL_CHOICE_STRINGS, "System Mailbox", X "Main Mailbox", X "Last Accessed Folder", X 0, X PANEL_NOTIFY_PROC, do_file_dir, X 0); X X add_folder_to_menu(folder_item, 3); X X save_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 163, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Save", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Save messages", X PANEL_CHOICE_STRINGS, "~/mbox", 0, X PANEL_NOTIFY_PROC, do_file_dir, X 0); X X add_folder_to_menu(save_item, 1); X X cd_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 220, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "chdir", 5, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Change Working Directory", X PANEL_CHOICE_STRINGS, "Print Current directory", X "HOME directory", X "Private Mail directory.", X "Help", 0, X PANEL_NOTIFY_PROC, do_file_dir, X 0); X X update_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 286, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Update", 6, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Updating folders", X PANEL_CHOICE_STRINGS, "Help", 0, X PANEL_NOTIFY_PROC, do_update, X 0); X X send_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 361, X PANEL_ITEM_Y, 50, X PANEL_SHOW_ITEM, FALSE, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Send", 6, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Send Letter", X PANEL_CHOICE_STRINGS, "Help", 0, X PANEL_NOTIFY_PROC, do_send, X 0); X X edit_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 436, X PANEL_ITEM_Y, 50, X PANEL_SHOW_ITEM, FALSE, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Editor", 4, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Editing", X PANEL_CHOICE_STRINGS, "Help", 0, X PANEL_NOTIFY_PROC, do_edit, X 0); X X abort_item = panel_create_item(main_panel, PANEL_BUTTON, X PANEL_ATTRIBUTE_LIST, button_args, X PANEL_ITEM_X, 511, X PANEL_ITEM_Y, 50, X PANEL_SHOW_ITEM, FALSE, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Abort", 5, fonts[LARGE]), X PANEL_NOTIFY_PROC, abort_mail, X 0); X X font_item = panel_create_item(main_panel, PANEL_CHOICE, X PANEL_ATTRIBUTE_LIST, choice_args, X PANEL_ITEM_X, 577, X PANEL_ITEM_Y, 50, X PANEL_LABEL_IMAGE, X panel_button_image(main_panel, "Fonts", 5, fonts[LARGE]), X PANEL_MENU_TITLE_STRING, "Fonts", X PANEL_SHOW_MENU_MARK, TRUE, X PANEL_CHOICE_FONTS, fonts[0], fonts[1], fonts[2], 0, X PANEL_CHOICE_STRINGS, "Default", "Small", "Large", 0, X PANEL_NOTIFY_PROC, change_font, X 0); X} X X/* X * Open the user's mail folder (either user set or default path) and find all X * the files (assumed to be mail folders) and add them to the menu list of X * folders to use. X */ Xadd_folder_to_menu(item, n) Xstruct panel_item *item; Xregister int n; X{ X register FILE *pp = NULL_FILE; X register char *p, *tmp = NULL; X int x = 0; X char buf[128], path[128]; X X if (!(p = do_set(set_options, "folder")) || !*p) X p = DEF_FOLDER; X if (p) { X tmp = getpath(p, &x); X if (x == -1) { X if (errno != ENOENT) X print("%s: %s\n", p, tmp); X tmp = NULL; X } X } X if (p = tmp) { X p = sprintf(buf, "%s %s", LS_COMMAND, p); X if (!(pp = popen(buf, "r"))) X error(buf); X else { X *path = '+'; X while (fgets(path+1, 128, pp)) { X struct stat s_buf; X if (p = index(path+1, '\n')) X *p = 0; X (void) sprintf(buf, "%s/%s", tmp, path+1); X if (stat(buf, &s_buf) || s_buf.st_mode & S_IFDIR) X continue; X panel_set(item, PANEL_CHOICE_STRING, n++, path, 0); X } X pclose(pp); X } X } X panel_set(item, PANEL_CHOICE_STRING, n, "Help", 0); X} END_OF_FILE if test 9189 -ne `wc -c <'main_panel.c'`; then echo shar: \"'main_panel.c'\" unpacked with wrong size! fi # end of 'main_panel.c' fi if test -f 'options.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'options.c'\" else echo shar: Extracting \"'options.c'\" \(7815 characters\) sed "s/^X//" >'options.c' <<'END_OF_FILE' X/* @(#)options.c (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */ X X#include "mush.h" X#include "options.h" X X/* X * NOTE: Any word flag which is a prefix of another word flag must be X * listed AFTER the flag it prefixes in the list below X */ X Xchar *word_flags[][2] = { X { "-bcc", "-b" }, X { "-blindcarbon", "-b" }, X { "-blind", "-b" }, X { "-carbon", "-c" }, X { "-cc", "-c" }, X { "-copy", "-c" }, X { "-curses", "-C" }, X { "-debug", "-d" }, X { "-echo", "-e" }, X { "-folder", "-f" }, /* Maybe -file should become -f too? */ X { "-file", "-F" }, /* Don't really like -file for -F */ X { "-headers", "-H" }, X { "-help", "-1" }, X { "-interact", "-i" }, X { "-mailbox", "-m" }, X { "-noheaders", "-N" }, X { "-noinit", "-n" }, X { "-readonly", "-r" }, X { "-shell", "-S" }, X { "-source", "-F" }, /* This is better for -F */ X { "-subject", "-s" }, X { "-sunhelp", "-2" }, X { "-timeout", "-T" }, X { "-tool", "-t" }, X { "-user", "-u" }, X { "-verbose", "-v" }, X { "-visual", "-C" }, X { NULL, NULL } /* This must be the last entry */ X}; X Xfix_word_flags(argv) Xregister char **argv; X{ X int i; X Debug(*argv); X for (++argv; *argv; argv++) { X for (i = 0; word_flags[i][0]; i++) { X int len = strlen(word_flags[i][0]); X if (! strncmp(*argv, word_flags[i][0], len)) { X char buf[BUFSIZ], *p = buf; X p += Strcpy(buf, word_flags[i][1]); X (void) strcpy(p, *argv + len); X (void) strcpy(*argv, buf); X } X } X Debug(" %s", *argv); X } X if (debug) X putchar('\n'); X} X X/* X * preparse the command line to determine whether or not we're going X * to bail out after checking that the user has no mail. Also, check X * to see if we're going to run a tool because it must be built first. X */ Xpreparse_opts(argcp, argv, argt) Xregister int *argcp; /* Pointer to argument count */ Xregister char **argv; /* Argument vector */ Xregister char ***argt; /* Pointer to tool-mode arg vector */ X{ X int n = FALSE; X char **args; X X#ifdef SUNTOOL X if (n = istool = strlen(prog_name) > 3 && X !strcmp(prog_name+strlen(prog_name)-4, "tool")) X turnon(glob_flags, DO_SHELL); X#endif /* SUNTOOL */ X X fix_word_flags(argv); X X if (!istool && *argcp > 1) { X for (args = argv+1; *args && args[0][0] == '-'; args++) { X int next = 1; XDoNext: X switch (args[0][next]) { X#ifdef SUNTOOL X case 'T' : X if (args[1]) X args++; X case 't' : X istool = 1; X n = TRUE; X turnon(glob_flags, DO_SHELL); X break; X#endif /* SUNTOOL */ X case 'S' : X turnon(glob_flags, DO_SHELL); X n = TRUE; X break; X case 'f' : X case 'F' : X case 'm' : X case 'u' : X n = TRUE; X case 'b' : X case 'c' : X case 's' : X case '1' : X case '2' : X if (args[1]) { X args++; X next = 0; X } X break; X case '\0': X next = 0; X default : ; X } X if (next) { X ++next; X goto DoNext; X } X } X if (*args) { /* unused args indicates sending mail to someone */ X n = TRUE; X if (!istool) X turnon(glob_flags, IS_SENDING); X } X } X X#ifdef SUNTOOL X /* even if not running tool mode parse all potential suntools args out */ X tool_parse_all(argcp, argv, argt, prog_name); X#endif /* SUNTOOL */ X X return n; X} X Xstatic char *usage_str = X#ifdef SUNTOOL X "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-t] [-s subject] [users]\n"; X#else X#ifdef CURSES X "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n"; X#else X "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n"; X#endif /* CURSES */ X#endif /* SUNTOOL */ X Xparse_options(argvp, flags) Xregister char ***argvp; Xstruct mush_flags *flags; X{ X char buf[256]; X X bzero(flags, sizeof (struct mush_flags)); X flags->source_rc = TRUE; X mailfile = ""; X X for (++(*argvp); **argvp && ***argvp == '-'; (*argvp)++) { X int look_again; XDoLookAgain: X look_again = TRUE; X switch ((*argvp)[0][1]) { X case 'e': X /* X * don't set tty modes -- e.g. echo and cbreak modes aren't X * changed. X */ X turnon(glob_flags, ECHO_FLAG); X#ifdef CURSES X when 'C': X /* don't init curses -- don't even set iscurses. */ X if (istool) { X puts("-C: You are already running in tool mode"); X turnoff(glob_flags, PRE_CURSES); X } else if (hdrs_only) X puts("headers only: ignoring -C flag"); X else X turnon(glob_flags, PRE_CURSES); X#endif /* CURSES */ X when 'F': X flags->src_n_exit = ((*argvp)[0][2] == '!'); X if (!(flags->src_file = *++(*argvp))) X puts("specify filename to source"), exit(1); X look_again = FALSE; X /* fall thru! */ X case 'N': X (void) strcat(flags->f_flags, "-N "); X when 'r': X (void) strcat(flags->f_flags, "-r "); /* folder() argument */ X when 'H': X if (istool) { X puts("running in tool-mode; -H option ignored."); X break; X } X turnoff(glob_flags, PRE_CURSES); X if (*(hdrs_only = (*(*argvp))+2) != ':') X hdrs_only = ":a"; X else X look_again = FALSE; X /* read only cuz no updates */ X (void) strcat(flags->f_flags, "-N -r "); X when 'i': X /* force interactive even if !isatty(0) */ X turnoff(glob_flags, REDIRECT); X when 'u': /* specify a user's mailbox */ X if (*mailfile) X puts("You can't specify more than one mailbox"), exit(1); X#ifdef HOMEMAIL X { X char *p; X int isdir = 1; X (void) sprintf(buf, "%%%s", X (*argvp)[1] ? (*argvp)[1] : "root"); X if ((p = getpath(buf, &isdir)) && !isdir) X strdup(mailfile, p); X else if (isdir < 0) X puts(p), exit(1); X else if (isdir) X printf("\"%s\" is a directory\n", p), exit(1); X } X#else /* HOMEMAIL */ X strdup(mailfile, sprintf(buf, "%s/%s", X MAILDIR, ((*argvp)[1])? (*argvp)[1] : "root")); X#endif /* HOMEMAIL */ X if ((*argvp)[1]) X ++(*argvp); X look_again = FALSE; X when 'm': X if ((*argvp)[1]) X strdup(spoolfile, *++(*argvp)); X else X printf("-m: missing mailbox name.\n"), exit(1); X look_again = FALSE; X when 'f': X if (*mailfile) X puts("You can't specify more than one mailbox"), exit(1); X if ((*argvp)[1]) { X strdup(mailfile, *++(*argvp)); X look_again = FALSE; X } else X strdup(mailfile, "&"); X when '1': X if ((*argvp)[1]) X strdup(cmd_help, *++(*argvp)); X else X puts("-1 \"filename\""), exit(1); X look_again = FALSE; X#ifdef SUNTOOL X when '2': X if ((*argvp)[1]) X strdup(tool_help, *++(*argvp)); X else X puts("-2 \"filename\""), exit(1); X look_again = FALSE; X#endif /* SUNTOOL */ X when 's': X if (istool) X puts("bad option when run as a tool"), exit(1); X else if ((*argvp)[1]) X flags->Subj = *++(*argvp); X else X puts("-s \"subject\""), exit(1); X look_again = FALSE; X when 'b': X if (istool) X puts("-b: bad option when run as a tool"), exit(1); X else if ((*argvp)[1]) X flags->Bcc = *++(*argvp); X else X puts("-b \"bcc list\""), exit(1); X look_again = FALSE; X when 'c': X if (istool) X puts("-c: bad option when run as a tool"), exit(1); X else if ((*argvp)[1]) X flags->Cc = *++(*argvp); X else X puts("-c \"cc list\""), exit(1); X look_again = FALSE; X break; X#ifdef VERBOSE_ARG X case 'v': X if (istool) X puts("bad option when run as a tool"), exit(1); X turnon(flags->flg, VERBOSE); X break; X#endif /* VERBOSE_ARG */ X#ifdef SUNTOOL X case 'T': X if ((time_out = atoi(*(*argvp))) <= 29) X time_out = 30; X look_again = FALSE; X /* -T implies -t */ X case 't': istool = 1; X#endif /* SUNTOOL */ X case 'S': turnon(glob_flags, DO_SHELL); X when 'n': flags->source_rc = FALSE; X when 'd': debug = 1; X when '\0' : look_again = FALSE; X otherwise: X print("%s: unknown option: `%c'\n", prog_name, X (*argvp)[0][1]? (*argvp)[0][1] : '-'); X print(usage_str, prog_name); X } X if (look_again && ++(**argvp) != '\0') X goto DoLookAgain; X } X} END_OF_FILE if test 7815 -ne `wc -c <'options.c'`; then echo shar: \"'options.c'\" unpacked with wrong size! fi # end of 'options.c' fi echo shar: End of archive 4 \(of 19\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 19 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.