[comp.sources.unix] v18i026: Mail user's shell version 6.4, Part04/19

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.