home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume18
/
mush
/
part07
< prev
next >
Wrap
Internet Message Format
|
1991-04-21
|
51KB
From: argv@zipcode.com (Dan Heller)
Newsgroups: comp.sources.misc
Subject: v18i064: mush - Mail User's Shell, Part07/22
Message-ID: <1991Apr21.025013.11375@sparky.IMD.Sterling.COM>
Date: 21 Apr 91 02:50:13 GMT
Approved: kent@sparky.imd.sterling.com
X-Checksum-Snefru: 5f3df319 237aaa55 fa7b288c 6ca14a4c
Submitted-by: Dan Heller <argv@zipcode.com>
Posting-number: Volume 18, Issue 64
Archive-name: mush/part07
Supersedes: mush: Volume 12, Issue 28-47
#!/bin/sh
# do not concatenate these parts, unpack them in order with /bin/sh
# file dates.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 7; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping dates.c'
else
echo 'x - continuing file dates.c'
sed 's/^X//' << 'SHAR_EOF' >> 'dates.c' &&
X
X (void) strncpy(zone, tz, 7), zone[7] = 0;
X return T;
}
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 */
char *
Time(opts, now)
register char *opts;
long now;
{
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, "%d", T->tm_year + 1900);
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
/* parse date and return a string that looks like
X * %ld%3c%s gmt_in_secs weekday orig_timezone
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 */
char *
parse_date(p)
register char *p;
{
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], Zone[12], dst[4];
X char a_or_p;
X int Month = 0, Day = 0, Year = 0;
X int Hours = -1, Mins = -1;
X struct tm T;
X
X Zone[0] = dst[0] = 0;
X skipspaces(0);
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 :-( Also reset
X * Zone[0] after any sscanf() that could corrupt it on a partial match.
X *
X * Not yet handling all possible combinations of mailers using two-word
X * time zones, e.g. MET DST instead of MEST. Only the specific case
X * where this was reported has been handled here.
X */
X
X /* RFC822 formats and minor variations -- order important */
X
X /* day_number month_name year_number time timezone */
X if (sscanf(p, "%d %s %d %d:%d:%*d %7s %3s",
X &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
X goto gotit;
X Zone[0] = dst[0] = 0;
X if (sscanf(p, "%d %s %d %d:%d %7s",
X &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
X goto gotit;
X Zone[0] = dst[0] = 0;
X /* day_name day_number month_name year_number time timezone */
X if (sscanf(p, "%*s %d %s %d %d:%d:%*d %7s %3s",
X &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
X goto gotit;
X Zone[0] = dst[0] = 0;
X if (sscanf(p, "%*s %d %s %d %d:%d %7s %3s",
X &Day, month, &Year, &Hours, &Mins, Zone, dst) >= 5 && Day)
X goto gotit;
X Zone[0] = dst[0] = 0;
X
X /* Ctime format (From_ lines) -- timezone almost never found */
X
X /* day_name month_name day_number time year_number */
X if (sscanf(p, "%*s %s %d %d:%d:%*d %d",
X month, &Day, &Hours, &Mins, &Year) == 5)
X goto gotit;
X /* day_name month_name day_number time timezone year_number */
X if (sscanf(p, "%*s %s %d %d:%d:%*d %7s %d",
X month, &Day, &Hours, &Mins, Zone, &Year) == 6)
X goto gotit;
X Zone[0] = 0;
X if (sscanf(p, "%*s %s %d %d:%d:%*d %7s %3s %d",
X month, &Day, &Hours, &Mins, Zone, dst, &Year) == 7)
X goto gotit;
X Zone[0] = dst[0] = 0;
X
X /* Other common variants */
X
X /* day_number month_name year_number time-timezone (day) */
X /* ^no colon separator */
X if (sscanf(p, "%d %s %d %2d%2d-%6[0123456789]",
X &Day, month, &Year, &Hours, &Mins, &Zone[1]) == 6) {
X Zone[0] = '-';
X goto gotit;
X }
X if (sscanf(p, "%d %s %d %2d%2d-%7s",
X &Day, month, &Year, &Hours, &Mins, Zone) == 6)
X goto gotit;
X Zone[0] = 0;
X
X /* day_number month_name year_number time timezone */
X /* ^no colon separator */
X /* (This is the odd one in the RFC822 examples section; */
X /* also catches the slop from partial hits above.) */
X if (sscanf(p, "%d %s %d %2d%2d %7s",
X &Day, month, &Year, &Hours, &Mins, Zone) >= 5 && Day)
X goto gotit;
X Zone[0] = 0;
X
X Zone[1] = 0; /* Yes, Zone[1] -- tested below */
X
X /* day_number month_name year_number, time "-" ?? */
X if (sscanf(p,"%d %s %d, %d:%d:%*d -%6[0123456789]",
X &Day, month, &Year, &Hours, &Mins, &Zone[1]) >= 5 && Day) {
X if (Zone[1])
X Zone[0] = '-';
X goto gotit;
X }
X
X /* day_number month_name year_number 12_hour_time a_or_p */
X if (sscanf(p, "%d %s %d %d:%d:%*d %cm %7s",
X &Day, month, &Year, &Hours, &Mins, &a_or_p, Zone) >= 6) {
X if (a_or_p == 'p')
X Hours += 12;
X goto gotit;
X }
X
X /* day_name month_name day_number year_number time */
X if (sscanf(p, "%*s %s %d %d %d:%d:%*d %7s",
X month, &Day, &Year, &Hours, &Mins, Zone) >= 5)
X goto gotit;
X Zone[0] = 0;
X if (sscanf(p, "%*s %s %d %d %d:%d %7s",
X month, &Day, &Year, &Hours, &Mins, Zone) >= 5)
X goto gotit;
X Zone[0] = 0;
X
X /* day_name month_name day_number time timezone year_number */
X if (sscanf(p, "%*s %s %d %d:%d:%*d %7s %d",
X month, &Day, &Hours, &Mins, Zone, &Year) == 6)
X goto gotit;
X Zone[0] = 0;
X if (sscanf(p, "%*s %s %d %d:%d %7s %d",
X month, &Day, &Hours, &Mins, Zone, &Year) == 6)
X goto gotit;
X Zone[0] = 0;
X
X /* day_number-month_name-year time */
X if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5)
X goto gotit;
X
X /* day_name, day_number-month_name-year time */
X if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",
X &Day, month, &Year, &Hours, &Mins) == 5)
X goto gotit;
X
X /* year_number-month_number-day_number time */
X if (sscanf(p, "%d-%d-%d %d:%d", &Year, &Month, &Day, &Hours, &Mins) == 5)
X goto gotit;
X
X /* month_name day_number time year Zone */
X /* (ctime, but without the day name) */
X if (sscanf(p, "%s %d %d:%d:%*d %d %7s",
X month, &Day, &Hours, &Mins, &Year, Zone) >= 5)
X goto gotit;
X Zone[0] = 0;
X
X if (ison(glob_flags, WARNING))
X print("Unknown date format: %s\n", p);
X return NULL;
X
gotit:
X if (!lcase_strncmp(dst, "dst", -1)) {
X (void) strcat(Zone, " ");
X (void) strcat(Zone, dst);
X }
X if (Year > 1900)
X Year -= 1900;
X if (!Month && (Month = month_to_n(month)) == -1) {
X print("bad month: %s\n", p);
X return NULL;
X }
X if (Zone[0] == 0) {
X /* Use local time zone if none found -- important for date_recv */
X (void) time_n_zone(Zone);
X }
X {
X /* Lots of foolishness with casts for Xenix-286 16-bit ints */
X
X long days_ctr; /* 16-bit ints overflowed Sept 12, 1989 */
X
X days_ctr = ((long)Year * 365L) + ((Year + 3) / 4);
X days_ctr += mtbl[Month-1] + Day + 6;
X if (Month > 2 && (Year % 4 == 0))
X days_ctr++;
X (void) (sprintf(Wkday, "%.3s", day_names[(int)(days_ctr % 7L)]));
X }
X T.tm_sec = 0; /* not recorded, so ignore it */
X T.tm_min = Mins;
X T.tm_hour = Hours;
X T.tm_mday = Day;
X T.tm_mon = Month - 1;
X T.tm_year = Year;
X T.tm_wday = T.tm_yday = 0; /* not used in time2gmt() */
X T.tm_isdst = 0; /* determined from Zone */
X return sprintf(month, "%ld%s%s", time2gmt(&T, Zone, 1), Wkday, Zone);
}
X
/* pass a string in the standard date format, put into string.
X * return values in buffers provided they are not null.
X */
char *
date_to_string(Date, Yr, Mon, Day, Wkday, Tm, Zone, ret_buf)
char *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *Zone, *ret_buf;
{
X long gmt;
X struct tm *T;
X char a_or_p, *p = ret_buf;
X
X Zone[0] = 0;
X (void) sscanf(Date, "%ld%3c%s", &gmt, Wkday, Zone);
X Wkday[3] = 0;
X gmt += getzoff(Zone);
X T = gmtime(&gmt);
X a_or_p = (T->tm_hour < 12)? 'a': 'p';
X
X (void) sprintf(Yr, "%d", T->tm_year + 1900);
X (void) sprintf(Day, "%d", T->tm_mday);
X (void) strcpy(Mon, month_names[T->tm_mon]);
X p += strlen(sprintf(p, "%s %2.d, ", Mon, T->tm_mday));
X
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, "%2.d:%02d%cm",
X (T->tm_hour)? (T->tm_hour <= 12)? T->tm_hour: T->tm_hour-12: 12,
X T->tm_min, a_or_p);
X (void) strcpy(Tm, p);
X
X return ret_buf;
}
X
/* pass a string in the internal mush date format.
X * return pointer to static buffer holding ctime-format date.
X */
char *
date_to_ctime(Date)
char *Date;
{
X static char ret_buf[32];
X long gmt;
X
X ret_buf[0] = 0;
X (void) sscanf(Date, "%ld", &gmt);
X (void) strcpy(ret_buf, ctime(&gmt));
X
X return ret_buf;
}
X
/*
X * Build a date string according to the specification in the RFC for Date:
X */
char *
rfc_date(buf)
char buf[];
{
X struct tm *T;
X char zone[8];
X
X T = time_n_zone(zone);
#ifndef USA
X {
X long zoff_hr, zoff_sec = getzoff(zone);
X if (zoff_sec < 0) {
X zone[0] = '-';
X zoff_sec = -zoff_sec;
X } else
X zone[0] = '+';
X zoff_hr = zoff_sec / 3600;
X zoff_sec -= zoff_hr * 3600;
X (void) sprintf(&zone[1], "%02d%02d", zoff_hr, zoff_sec / 60);
X }
#endif /* !USA */
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 + 1900, /* year number */
X T->tm_hour, /* hours (24hr) */
X T->tm_min, T->tm_sec, /* mins/secs */
X zone); /* timezone */
}
X
#define JAN 1
#define FEB 2
#define MAR 3
#define APR 4
#define MAY 5
#define JUN 6
#define JUL 7
#define AUG 8
#define SEP 9
#define OCT 10
#define NOV 11
#define DEC 12
X
/* stolen direct from ELM */
month_to_n(name)
register char *name;
{
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 }
}
SHAR_EOF
echo 'File dates.c is complete' &&
chmod 0644 dates.c ||
echo 'restore of dates.c failed'
Wc_c="`wc -c < 'dates.c'`"
test 15621 -eq "$Wc_c" ||
echo 'dates.c: original size 15621, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= digestify ==============
if test -f 'digestify' -a X"$1" != X"-c"; then
echo 'x - skipping digestify (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting digestify (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'digestify' &&
#! ../bin/mush -F!
#
# Mush digestifier. Makes a folder or a list of messages into a digest.
#
# A "digest" is a collection of E-mail messages bundled together into a
# single message for ease of redistribution. The individual messages
# in the digest are called "articles". Each article has a small set of
# essential headers (usually From:, Date:, and Subject:) and is divided
# from the preceding and following articles by an "article separator"
# string (usually eight hyphens, "--------"). The Mush built-in command
# "undigest" unpacks most digests, including those made by this script.
#
# Usage:
# From your shell: digestify -f mailbox
# From within mush:
# First: cmd digest "set digest = '\!*' ; source digestify"
# Then: digest [msg-list]
# Or: message-selection-command | digest
#
# Note that by default it makes a digest of the ENTIRE folder!
#
X
#
# Rudimentary sanity checks
#
if ! $?version
X echo "You must have Mush version 7.0 or higher to run this script"
X exit
endif
if ! $?thisfolder
X echo "You can't use this script as an init file; try using -F"
X exit
endif
X
#
# Set up defaults
#
if ! $?digest
X set digest = *
X if $?interact
X unset interact # Assume non-interactive if no input list
X endif
else
X set interact # Note that this is interactive
X if "X$digest" == X
X set digest = * # Default to all messages for empty input
X else
X $digest | set digest # Pre-expand message numbers
X endif
endif
X
#
# Suppress any "that isn't set" messages from "unset"
#
if $?warning
X set savewarn
endif
unset warning oldpre oldpost oldindent oldign oldshow
X
#
# Save everything in case the user wants it back.
# Could wrap all this with "if $?interact" but this script
# might be read by "mush -F", in which case we need this.
#
if $?pre_indent_str
X set oldpre = "$pre_indent_str"
endif
if $?post_indent_str
X set oldpost = "$post_indent_str"
endif
if $?indent_str
X set oldindent = "$indent_str"
endif
if $?alwaysignore
X set oldign = "$alwaysignore"
endif
if $?show_hdrs
X set oldshow = "$show_hdrs"
endif
if $?quiet
X set oldquiet = "$quiet"
endif
if $?no_expand
X set savenoex
endif
X
#
# Prepare to form the digest.
#
set indent_str no_expand alwaysignore=include quiet=await,newmail
unset post_indent_str
alias DIGEST $thisfolder # Any target in place of $thisfolder
set pre_indent_str="--------" # Insert your digest separator here
set show_hdrs=from,date,subject # Add any other headers you want
X
#
# Now do it. All that work for a two-line operation ....
# NOTE: If you change DIGEST above, remove the "await" command here!
# Backslashes prevent any cmd expansion from confusing us.
#
\delete $digest
\mail -UH /dev/null -I $digest -s "Digest of $thisfolder" DIGEST; \await -T 1
X
#
# Clean out the deleted stuff if not interactive
#
if ! $?interact
X \update
endif
X
#
# Be neat and put everything back the way it was.
#
unset indent_str no_expand alwaysignore quiet pre_indent_str show_hdrs
unalias DIGEST
if $?savenoex
X set no_expand
endif
if $?oldquiet
X set quiet = "$oldquiet"
endif
if $?oldpre
X set pre_indent_str = "$oldpre"
endif
if $?oldpost
X set post_indent_str = "$oldpost"
endif
if $?oldindent
X set indent_str = "$oldindent"
endif
if $?oldign
X set alwaysignore = "$oldign"
endif
if $?oldshow
X set show_hdrs = "$oldshow"
endif
unset oldpre oldpost oldindent oldign oldshow oldquiet nonoex digest
if $?savewarn
X unset savewarn
X set warning
endif
SHAR_EOF
chmod 0755 digestify ||
echo 'restore of digestify failed'
Wc_c="`wc -c < 'digestify'`"
test 3468 -eq "$Wc_c" ||
echo 'digestify: original size 3468, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= doproc.c ==============
if test -f 'doproc.c' -a X"$1" != X"-c"; then
echo 'x - skipping doproc.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting doproc.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'doproc.c' &&
/* @(#)doproc.c (c) copyright 10/18/86 (Dan Heller) */
X
/* do main panel item procedures */
#include "mush.h"
X
extern void start_textsw_edit();
extern Panel get_compose_panel();
void set_comp_items();
X
extern Panel_item
X file_item, folder_text_item, folder_item, msg_num_item, read_item,
X reply_item, save_item, sub_hdr_item[6];
X
/* following macro is for the next two procedures */
#define hdr_item(item) \
X (item == sub_hdr_item[0] || item == sub_hdr_item[1] || \
X item == sub_hdr_item[2] || item == sub_hdr_item[3] || \
X item == sub_hdr_item[4] || item == sub_hdr_item[5])
X
void
delete_mail(item, value, event)
register Panel_item item;
int value;
register Event *event;
{
X int val = value; /* save cuz we reset value immediately */
X u_long bang = ison(glob_flags, IGN_BANG);
X char buf[128];
X
X (void) panel_set(item, PANEL_VALUE, 0, 0);
X if (hdr_item(item) && event_id(event) != MS_LEFT || val == 2) {
X help(0, "delete", tool_help);
X return;
X }
X /* delete current message */
X wprint(sprintf(buf, "\\%sdelete %s\n",
X ((event_id(event) == MS_LEFT || val == 0)? "" : "un"),
X panel_get_value(msg_num_item)) + 1); /* +1 skips the backslash */
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
}
X
void
read_mail(item, value, event)
Panel_item item;
Event *event;
{
X int this_msg = current_msg;
X
X /* check "event" in case we were called from hdr_sw.c
X * in which case event would be NULL
X */
X if (event && event_id(event) == MS_RIGHT && item &&
X (item == read_item ||
X (item == sub_hdr_item[0] || item == sub_hdr_item[1]))) {
X (void) help(0, "next", tool_help);
X return;
X }
X if (item && (item == sub_hdr_item[4] || item == sub_hdr_item[5])) {
X (void) help(0, "Menu Read", tool_help);
X return;
X }
X if (!msg_cnt) {
X wprint ("No Mail.\n");
X return;
X }
X if (item && item == read_item || ison(msg[current_msg].m_flags, DELETE))
X (void) next_msg();
X if (this_msg != current_msg || ison(msg[current_msg].m_flags, UNREAD) ||
X (current_msg < n_array[0] || current_msg > n_array[screen])) {
X set_isread(current_msg);
X (void) do_hdrs(0, DUBL_NULL, NULL);
X }
X if (isoff(msg[current_msg].m_flags, DELETE))
X display_msg(current_msg, (u_long)0);
}
X
/* the panel button that says "filename" and "directory", etc... text item */
Panel_setting
file_dir(item, event)
Panel_item item;
Event *event;
{
X register char *p;
X u_long bang = ison(glob_flags, IGN_BANG);
X char buf[MAXPATHLEN];
X
X if (event_id(event) == ESC) {
X /* file expansion request */
X int n;
X char **files;
X p = panel_get_value(item);
X (void) sprintf(buf, "%s*", p);
X timeout_cursors(1);
X if ((n = filexp(buf, &files)) > 0) {
X Debug("%d: ",n), print_argv(files);
X if (n > 1) {
X n = lcprefix(files, 0);
X files[0][n] = 0;
X }
X panel_set_value(item, trim_filename(files[0]));
X free_vec(files);
X } else
X errbell(n); /* see curs_io.c */
X timeout_cursors(0);
X return PANEL_NONE;
X }
X
X if (item == folder_text_item) {
X (void) sprintf(buf, "folder %s %s",
X (ison(glob_flags, READ_ONLY) || ison(glob_flags, DO_UPDATE) &&
X !ask("Folder has been modified. Update changes?"))? "!" : "",
X panel_get_value(folder_text_item));
X }
X else if (item == file_item) {
X register char *b = buf;
X char msgstr[BUFSIZ];
X
X if (event_id(event) == '\n' || event_id(event) == '\r')
X b += Strcpy(buf, "save ");
X else
X b += Strcpy(buf, "write ");
X if ((p = panel_get_value(msg_num_item)) && *p)
X b += Strcpy(b, p);
X else {
X if (ison(msg[current_msg].m_flags, DELETE) &&
X !do_set(set_options, "show_deleted")) {
X (void) sprintf(msgstr, "Message %d deleted -- save anyway?",
X current_msg+1);
X if (ask(msgstr) != TRUE) {
X wprint("Message not saved\n");
X return PANEL_NONE;
X }
X }
X b += strlen(sprintf(b, "%d", current_msg+1));
X }
X *b++ = ' ', *b = 0;
X if (!(p = panel_get_value(item)) || !*p &&
X (!(p = do_set(set_options, "mbox")) || !*p))
X p = DEF_MBOX;
X if (chk_option("verify", "save")) {
X (void) sprintf(msgstr, "%s in \"%s\"?", buf, trim_filename(p));
X if (ask(msgstr) != TRUE) {
X wprint("Message not saved\n");
X return PANEL_NONE;
X }
X }
X (void) strcpy(b, p); /* now add to command */
X }
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X return PANEL_NONE;
}
X
#ifndef NO_WALK_MENUS
void
xx_file_dir(item, value)
Panel_item item;
char * value;
{
X char buf[BUFSIZ];
X u_long bang = ison(glob_flags, IGN_BANG);
X
X if (item == folder_item) {
X (void) sprintf(buf, "folder %s ",
X (ison(glob_flags, READ_ONLY) || ison(glob_flags, DO_UPDATE) &&
X !ask("Folder has been modified. Update changes?"))? "!" : "");
X strcat(buf, value);
X } else if (item == save_item) {
X char msgstr[BUFSIZ], *p;
X register char *p2 = (char *)panel_get_value(msg_num_item);
X (void) strcpy(buf, "save ");
X
X if (p2 && *p2) {
X (void) strcat(buf, p2);
X (void) strcat(buf, " ");
X }
X (void) strcat(buf, value);
X if (chk_option("verify", "save")) {
X (void) sprintf(msgstr, "Save in %s? ", trim_filename(value));
X if (ask(msgstr) != TRUE) {
X wprint("Message not saved\n");
X return;
X }
X }
X }
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X (void) panel_set(item, PANEL_VALUE, 0, NULL); /* remove last value */
}
X
/*
X * callback routine for the panel items that need filename input.
X * (folder and save)
X */
void
do_file_dir(item, event)
Panel_item item;
Event *event;
{
X if (item == folder_item) {
X char *p = panel_get_value(folder_text_item);
X if (!*p) {
X ok_box("Enter folder name.");
X return;
X }
X xx_file_dir(item, p);
X } else if (item == save_item) {
X if (!strcmp("Filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
X event_id(event) = '\n'; /* let file_dir think it got a \n */
X file_dir(file_item, event);
X return;
X }
X }
X (void) panel_set(item, PANEL_VALUE, 0, NULL); /* remove last value */
}
#else /* NO_WALK_MENUS */
X
/*
X * callback routine for the panel items that need filename input.
X * (folder and save)
X */
void
do_file_dir(item, value, event)
Panel_item item;
int value;
Event *event;
{
X char buf[BUFSIZ];
X u_long bang = ison(glob_flags, IGN_BANG);
X
X if (item == folder_item) {
X (void) sprintf(buf, "folder %s ",
X (ison(glob_flags, READ_ONLY) || ison(glob_flags, DO_UPDATE) &&
X !ask("Folder has been modified. Update changes?"))? "!" : "");
X if (event_id(event) == MS_LEFT) {
X char *p = panel_get_value(folder_text_item);
X if (!*p) {
X ok_box("Enter folder name.");
X return;
X }
X (void) strcat(buf, p);
X } else if (!value)
X (void) strcat(buf, "%");
X else if (value == 1)
X (void) strcat(buf, "&");
X else if (value == 2)
X (void) strcat(buf, "#");
X else
X (void) strcat(buf, panel_get(item, PANEL_CHOICE_STRING, value));
X } else if (item == save_item) {
X char msgstr[BUFSIZ], *p;
X (void) strcpy(buf, "save ");
X if (event_id(event) == MS_LEFT) {
X if (!strcmp("Filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
X event_id(event) = '\n'; /* let file_dir think it got a \n */
X file_dir(file_item, event);
X return;
X }
X } else if (value == 0) {
X register char *p2 = (char *)panel_get_value(msg_num_item);
X
X if (!(p = do_set(set_options, "mbox")) || !*p)
X p = DEF_MBOX;
X if (p2 && *p2) {
X (void) strcat(buf, p2);
X (void) strcat(buf, " ");
X }
X (void) strcat(buf, p);
X } else
X (void) strcat(buf, p = panel_get(item, PANEL_CHOICE_STRING, value));
X if (chk_option("verify", "save")) {
X (void) sprintf(msgstr, "Save in %s? ", trim_filename(p));
X if (ask(msgstr) != TRUE) {
X wprint("Message not saved\n");
X return;
X }
X }
X }
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X (void) panel_set(item, PANEL_VALUE, 0, NULL); /* remove last value */
}
#endif /* NO_WALK_MENUS */
X
/*ARGSUSED*/
void
do_help(item, value, event)
Panel_item item;
register int value;
Event *event;
{
X register char *p, *helpfile = tool_help;
X if (!event || event_id(event) == MS_LEFT)
X value = 0;
X switch(value) {
X case 0: p = "about", helpfile = cmd_help;
X when 1: p = "help";
X when 2: p = "mouse";
X when 3: p = "windows";
X when 4: p = "hdr_format", helpfile = cmd_help;
X when 5: p = "msg_list", helpfile = cmd_help;
X when 6: p = "folder";
X otherwise: p = "general";
X }
X (void) help(0, p, helpfile);
}
X
/*ARGSUSED*/
void
do_update(item, value, event)
Panel_item item;
int value;
Event *event;
{
X char *argv[2];
X if (event && event_id(event) != MS_LEFT) {
X if (value == 0) {
X if (check_new_mail() == 0)
X print("No new mail.\n");
X } else
X (void) help(0, "update", tool_help);
X return;
X }
X argv[0] = "update";
X argv[1] = NULL;
X timeout_cursors(TRUE);
X (void) folder(0, argv, NULL);
X timeout_cursors(FALSE);
}
X
/*ARGSUSED*/
void
toolquit(item, value, event)
Panel_item item;
int value;
Event *event;
{
X void wmgr_changestate(), wmgr_changelevel();
X register int which;
X
X if (!value || event_id(event) == MS_LEFT) {
X if (ison(glob_flags, DO_UPDATE)) {
X do_update(NO_ITEM, 0, NO_EVENT);
X turnoff(glob_flags, NEW_MAIL);
X }
X check_icons();
X mail_status(0); /* lower flag (if up) print current num of msgs */
X /* wmgr_changestate (window_get(tool, WIN_FD), rootfd, TRUE); */
X /* wmgr_changelevel (window_get(tool, WIN_FD), parentfd, TRUE); */
X close_frame();
X window_set(tool, FRAME_CLOSED, TRUE, NULL);
X is_iconic = ((int) window_get(tool, FRAME_CLOSED));
X return;
X } else if (value == 2) {
X (void) help(0, "quit", tool_help);
X return;
X }
X /* modify this to check for "abort" choice when ternary return values
X * are possible!
X */
X if (isoff(glob_flags, DO_UPDATE) ||
X ask("Folder has been modified -- update?")) {
X if (!copyback("Quit anyway?", TRUE))
X return;
X }
X cleanup(0);
}
X
/*ARGSUSED*/
void
do_mark(item, value, event)
Panel_item item;
int value;
Event *event;
{
X if (event && (event_id(event) == MS_LEFT) || value == 0) {
X int msg_num = event? current_msg : (int)item;
X /* mark message */
X if (ison(msg[msg_num].m_flags, M_PRIORITY(0)))
X turnoff(msg[msg_num].m_flags, M_PRIORITY(0));
X else
X turnon(msg[msg_num].m_flags, M_PRIORITY(0));
X (void) do_hdrs(0, DUBL_NULL, NULL);
X } else if (value < 7) {
X /* set priority */
X char buf[90];
X (void) cmd_line(sprintf(buf, "mark -%c %s",
X value < 6? value + 'A' - 1 : ' ',
X panel_get_value(msg_num_item)), NULL);
X } else
X (void) help(0, "mark", tool_help);
X if (value != 7 && item)
X panel_set_value(item, 0);
}
X
/*ARGSUSED*/
void
do_lpr(item, value, event)
Panel_item item;
int value;
Event *event;
{
X char buf[128];
X
X if (event && (event_id(event) == MS_LEFT)) {
X wprint("Sending message %d to printer...\n", current_msg+1);
X (void) strcpy(buf, "lpr ");
X if (value)
X (void) sprintf(buf, "lpr \"%s\"", panel_get_value(msg_num_item));
X timeout_cursors(TRUE);
X (void) cmd_line(buf, msg_list);
X timeout_cursors(FALSE);
X } else
X (void) help(0, "printer", tool_help);
}
X
/* panel selection button pressed to send a letter.
X * we've attached the sign panel item to this item to 1) avoid
X * using a global and 2) make it general enough so that multiple
X * compose windows can have multiple send_items and we can
X * identify which sign/fortune items are associated with this
X * particular letter. The fortune item is attached to the sign
X * item.
X */
/*ARGSUSED*/
void
do_send(item, value, event)
Panel_item item;
int value;
register Event *event;
{
X Panel panel = (Panel)panel_get(item, PANEL_PARENT_PANEL);
X Panel_item sign_item = (Panel_item)panel_get(item, PANEL_CLIENT_DATA);
X Panel_item fortune_item =
X (Panel_item)panel_get(sign_item, PANEL_CLIENT_DATA);
X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
X char *argv[5], buf[64];
X char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
X char *p, *oldsign = NULL, *oldfortune = NULL;
X
X if (textsw_store_file(textsw, file, 0, 0)) {
X error("Can't save to %s", file);
X return;
X }
X /* check if user changed variables before sending */
X if (p = do_set(set_options, "autosign"))
X oldsign = savestr(p);
X if (panel_get_value(sign_item) && !oldsign)
X cmd_line(strcpy(buf, "\\set autosign"), NULL);
X else if (!panel_get_value(sign_item) && oldsign)
X cmd_line(strcpy(buf, "\\unset autosign"), NULL);
X if (p = do_set(set_options, "fortune"))
X oldfortune = savestr(p);
X if (panel_get_value(fortune_item) && !oldfortune)
X (void) cmd_line(strcpy(buf, "\\set fortune"), NULL);
X else if (!panel_get_value(fortune_item) && oldfortune)
X (void) cmd_line(strcpy(buf, "\\unset fortune"), NULL);
X turnoff(glob_flags, IS_GETTING);
X argv[0] = "mail";
X argv[1] = "-Uh";
X argv[2] = file;
X argv[3] = NULL;
X clear_msg_list(msg_list);
X timeout_cursors(TRUE);
X if (do_mail(3, argv, msg_list) == 0) {
X (void) unlink(file);
X set_comp_items(panel);
X }
X if (panel_get_value(sign_item) && !oldsign)
X (void) cmd_line(strcpy(buf, "\\unset autosign"), NULL);
X else if (!panel_get_value(sign_item) && oldsign) {
X argv[0] = "set";
X argv[1] = "autosign";
X if (*oldsign) {
X argv[2] = "=";
X argv[3] = oldsign;
X argv[4] = NULL;
X (void) set(4, argv, NULL);
X } else {
X argv[2] = NULL;
X (void) set(2, argv, NULL);
X }
X }
X if (panel_get_value(fortune_item) && !oldfortune)
X cmd_line(strcpy(buf, "\\unset fortune"), NULL);
X else if (!panel_get_value(fortune_item) && oldfortune) {
X argv[0] = "set";
X argv[1] = "fortune";
X if (*oldfortune) {
X argv[2] = "=";
X argv[3] = oldfortune;
X argv[4] = NULL;
X (void) set(4, argv, NULL);
X } else {
X argv[2] = NULL;
X (void) set(2, argv, NULL);
X }
X }
X xfree(oldsign), xfree(oldfortune);
X timeout_cursors(FALSE);
}
X
/*ARGSUSED*/
void
do_include(item, value, event)
Panel_item item;
int value;
Event *event;
{
X extern FILE *ed_fp;
X char *p, buf[64], *file;
X Textsw textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
X PANEL_CLIENT_DATA);
X
X if (event && event_id(event) == MS_LEFT)
X value = 0;
X if (value == 2) {
X (void) help(0, "include", tool_help);
X return;
X }
X p = panel_get_value(msg_num_item);
X (void) sprintf(buf, "%c%c%s", *escape, value == 0? 'i' : 'f', p? p : "");
X
X file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
X if (textsw_store_file(textsw, file, 0, 0)) {
X (void) ask("Something's wrong... Click anything.");
X return;
X }
X if (ed_fp) {
X (void) ask("tmpfile already in use... Click anything.");
X (void) fclose(ed_fp);
X }
X if (!(ed_fp = mask_fopen(file, "a"))) {
X error("Cannot open %s to append msg.", file);
X return;
X }
X (void) add_to_letter(buf);
X (void) fclose(ed_fp), ed_fp = NULL_FILE;
#ifdef SUN_4_0 /* SunOS 4.0+ */
X window_set(textsw, TEXTSW_FILE_CONTENTS, file, NULL);
#else /* SUN_4_0 */
X textsw_load_file(textsw, file, 1, 0, 0);
#endif /* SUN_4_0 */
X window_set(textsw, TEXTSW_UPDATE_SCROLLBAR, NULL);
X (void) unlink(file);
}
X
/*ARGSUSED*/
void
do_compose(item, value, event)
Panel_item item;
int value;
Event *event;
{
X char buf[5];
X
X if (event && event_id(event) != MS_LEFT) {
X (void) help(0, "compose", tool_help);
X return;
X }
X open_compose();
X if (!compose_frame)
X return; /* open failed */
X clear_msg_list(msg_list);
X if (do_mail(0, DUBL_NULL, msg_list) == 0) {
X Panel panel = get_compose_panel();
X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
X start_textsw_edit(textsw, TRUE);
X set_comp_items(panel);
X }
}
X
/*
X * notify proc for reply button -- also called from select.c (do_menu()) ,
X * in which case "event" is null and "value" contains the message
X * number of the message to reply to.
X */
/*ARGSUSED*/
void
respond_mail(item, value, event)
Panel_item item;
int value;
Event *event;
{
X int tmp = current_msg;
X char buf[256];
X
X if (event && event_id(event) == MS_LEFT)
X value = 0;
X if (event && value == 4) {
X (void) help(0, "respond", tool_help);
X return;
X }
X if (!msg_cnt) {
X wprint("No messages to respond to.\n");
X return;
X }
X if (ison(glob_flags, IS_GETTING)) {
X wprint("Finish editing current message first.\n");
X return;
X }
X if (!event)
X tmp = value, value = 0;
X open_compose();
X if (!compose_frame)
X return; /* open failed */
X (void) sprintf(buf, "%s %s %d",
X (value == 2 || value == 3)? "\\replyall" : "\\replysender",
X (value == 1 || value == 3)? "-i": NO_STRING, tmp+1);
X if (cmd_line(buf, NULL) != -1) {
X Panel panel = get_compose_panel();
X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
X wprint("Responding to message %d\n", tmp+1);
X start_textsw_edit(textsw, FALSE);
X set_comp_items(panel);
X }
}
X
/*ARGSUSED*/
void
load_from_file(item, value, event)
Panel_item item;
int value;
Event *event;
{
X int x = 0;
X Textsw textsw;
X Panel_item filename_item = (Panel_item)panel_get(item, PANEL_CLIENT_DATA);
X char *file, *p = panel_get_value(filename_item);
#ifndef SUN_4_0 /* SunOS 4.0+ */
X char *sfile, buf[128];
X extern FILE *ed_fp;
#endif /* SUN_4_0 */
X
X if (!*p) {
X wprint("Specify Filename.\n");
X return;
X }
X file = getpath(p, &x);
X if (x == 1)
X wprint("%s: is a directory.\n", p);
X else if (x == -1)
X wprint("%s: %s\n", p, file);
X if (x)
X return;
X timeout_cursors(TRUE);
X textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
X PANEL_CLIENT_DATA);
X if (event_id(event) != MS_LEFT && value == 1)
X /* replace */
X textsw_load_file(textsw, file, 1, 0, 0);
X else {
X /* insert */
#ifdef SUN_4_0 /* SunOS 4.0+ */
X window_set(textsw, TEXTSW_INSERT_FROM_FILE, file, NULL);
#else /* SUN_4_0 */
X /* best we can do with pre 4.0 is save the current file
X * and append the new file onto the end.
X */
X sfile = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
X if (textsw_store_file(textsw, sfile, 0, 0)) {
X (void) ask("Can't save file... Click anything.");
X return;
X }
X if (ed_fp) {
X (void) ask("tmpfile already in use... Click anything.");
X fclose(ed_fp);
X }
X if (!(ed_fp = mask_fopen(sfile, "a"))) {
X error("Cannot open %s.", sfile);
X return;
X }
X (void) sprintf(buf, "%c%c%s", *escape, 'r', trim_filename(p));
X (void) add_to_letter(buf);
X (void) fclose(ed_fp), ed_fp = NULL_FILE;
X textsw_load_file(textsw, sfile, 1, 0, 0);
X (void) unlink(sfile);
#endif /* SUN_4_0 */
X }
X window_set(textsw, TEXTSW_UPDATE_SCROLLBAR, NULL);
X panel_set_value(item, 0);
X timeout_cursors(FALSE);
}
X
/*ARGSUSED*/
void
save_to_file(item, value, event)
Panel_item item;
Event *event;
{
X Panel_item filename_item = panel_get(item, PANEL_CLIENT_DATA);
X char *file = panel_get_value(filename_item);
X FILE *fp;
X Textsw textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
X PANEL_CLIENT_DATA);
X
X if (!*file) {
X wprint("Specify Filename\n");
X return;
X }
X timeout_cursors(TRUE);
X /* append to file -- no confirmation necessary */
X if (fp = open_file(file, FALSE, TRUE)) {
X char buf[BUFSIZ];
X Textsw_index next_pos = 0, tmp;
X Textsw_index length =
X (Textsw_index)window_get(textsw, TEXTSW_LENGTH);
X do {
X tmp = next_pos;
X next_pos = (Textsw_index) window_get(textsw, TEXTSW_CONTENTS,
X next_pos, buf, sizeof(buf));
X if (fwrite(buf, sizeof(char), (int)(next_pos - tmp), fp) == 0)
X error("%s may be incomplete", file);
X } while (next_pos < length);
X (void) close_lock(file, fp);
X wprint("Wrote %d bytes to %s\n", length, trim_filename(file));
X }
X timeout_cursors(FALSE);
}
X
void
abort_mail(item, event)
Panel_item item;
Event *event;
{
X Panel panel = (Panel)panel_get(item, PANEL_PARENT_PANEL);
X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
X wprint("Aborted letter.\n");
X textsw_reset(textsw, 0, 0);
X rm_edfile(0);
X set_comp_items(panel);
}
X
/* set the compose panel items */
void
set_comp_items(panel)
Panel panel;
{
X Panel_item item, next;
X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
X int getting = ison(glob_flags, IS_GETTING) != 0;
X int i = 0;
X
X window_set(textsw, TEXTSW_READ_ONLY, !getting, NULL);
X /* remove next line when multiple composes become a reality */
X (void) panel_set(reply_item, PANEL_SHOW_ITEM, !getting, NULL);
X /* skip "close" item */
X item = (Panel_item) panel_get(panel, PANEL_FIRST_ITEM);
X for (item = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
X item; item = next) {
X next = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
X (void) panel_set(item,
X PANEL_SHOW_ITEM, (i++ < 1)? !getting : getting, NULL);
X }
}
X
/*
X * Ask a yes/no question and return an answer: TRUE or FALSE.
X */
ask(question)
char *question;
{
#ifdef SUN_4_0 /* SunOS 4.0+ */
X return alert_prompt(tool, (Event *)NULL,
X ALERT_MESSAGE_STRINGS, question, NULL,
X ALERT_BUTTON_YES, "Yes",
X ALERT_BUTTON_NO, "No",
X NULL) == ALERT_YES;
#else /* SUN_4_0 */
X Event event;
X struct prompt prompt;
X Rect *rect = (Rect *)window_get(tool, WIN_RECT);
X char buf[MAXPATHLEN];
X
X (void) sprintf(buf,
X "%s \nPress LEFT Button to Confirm. Anything else to cancel.",
X question);
X prompt.prt_rect.r_left = rect->r_left + (rect->r_width / 3);
X prompt.prt_rect.r_top = rect->r_top + (rect->r_height / 3);
X prompt.prt_rect.r_width = prompt.prt_rect.r_height = PROMPT_FLEXIBLE;
X prompt.prt_font = mush_font;
X prompt.prt_text = buf;
X
X menu_prompt(&prompt, &event, window_get(tool, WIN_FD));
X return event_id(&event) == MS_LEFT;
#endif /* SUN_4_0 */
}
X
void
ok_box(buf)
char *buf;
{
#ifdef SUN_4_0
X (void) alert_prompt(tool, (Event *)NULL,
X ALERT_MESSAGE_STRINGS, buf, NULL,
X ALERT_BUTTON_YES, "Ok",
X NULL);
#else /* SUN_4_0 */
X Event event;
X struct prompt prompt;
X Rect *rect = (Rect *)window_get(tool, WIN_RECT);
X (void) strcat(buf, " \nPress LEFT Button to Continue.");
X prompt.prt_rect.r_left = rect->r_left + (rect->r_width / 3);
X prompt.prt_rect.r_top = rect->r_top + (rect->r_height / 3);
X prompt.prt_rect.r_width = prompt.prt_rect.r_height = PROMPT_FLEXIBLE;
X prompt.prt_font = mush_font;
X prompt.prt_text = buf;
X menu_prompt(&prompt, &event, window_get(tool, WIN_FD));
#endif /* SUN_4_0 */
}
X
Panel_setting
msg_num_done(item, event)
Panel_item item;
Event *event;
{
X char buf[82];
X u_long bang = ison(glob_flags, IGN_BANG);
X register char *p;
X int n;
X
X if (event_id(event) != '\n' && event_id(event) != '\r') {
X (void) help(0, "message range", tool_help);
X return PANEL_NONE;
X }
X (void) sprintf(buf, "headers %s", (p = (char *)panel_get_value(item)));
X (void) panel_set(item, PANEL_VALUE, NO_STRING, NULL);
X if (!(n = chk_msg(p)))
X return PANEL_NONE;
X current_msg = --n;
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X (void) display_msg(n, (u_long)0);
X return PANEL_NONE;
}
X
void
do_sort(item, value, event)
Panel_item item;
int value;
Event *event;
{
X char *argv[3], list[MAXMSGS_BITS];
X char *p = (char *)panel_get_value(msg_num_item);
X int n = 0;
X
X if (p && *p) {
X argv[0] = p;
X argv[1] = NULL;
X n = get_msg_list(argv, list);
X }
X argv[0] = "sort";
X argv[2] = NULL;
X
X if (event_id(event) == MS_LEFT)
X value = 0;
X switch(value) {
X case 0: argv[1] = "S";
X when 1: argv[1] = "a";
X when 2: argv[1] = "l";
X when 3: argv[1] = "R";
X when 4: argv[1] = "s";
X when 5: argv[1] = "d";
X when 6: argv[1] = "p";
X when 7: do_set(set_options, "sort");
X when 8: (void) help(0, "sort", tool_help);
X }
X if (value != 8) {
X if (n > 0) {
X turnon(glob_flags, IS_PIPE);
X (void) sort(2, argv, list);
X turnoff(glob_flags, IS_PIPE);
X } else
X (void) sort(2, argv, NULL);
X (void) do_hdrs(0, DUBL_NULL, NULL);
X }
X (void) panel_set(item, PANEL_VALUE, 0, NULL);
}
X
void
do_options(item, value, event)
Panel_item item;
int value;
Event *event;
{
X if (event_id(event) == MS_LEFT) {
X view_options();
X return;
X }
X switch (value) {
X case 0:
X view_options();
X when 1:
X do_ignore();
X when 2:
X do_aliases();
X }
}
SHAR_EOF
chmod 0644 doproc.c ||
echo 'restore of doproc.c failed'
Wc_c="`wc -c < 'doproc.c'`"
test 24153 -eq "$Wc_c" ||
echo 'doproc.c: original size 24153, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= execute.c ==============
if test -f 'execute.c' -a X"$1" != X"-c"; then
echo 'x - skipping execute.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting execute.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'execute.c' &&
/* execute.c (c) copyright 10/28/86 (Dan Heller) */
X
#include "mush.h"
#ifdef BSD
#include <sys/wait.h>
#else
#ifndef SYSV
#include <wait.h>
#endif /* SYSV */
#endif /* BSD */
X
#ifdef lint
#include <sys/resource.h>
#endif /* lint */
X
static jmp_buf execjbuf;
X
#ifdef SUNTOOL
X
/*ARGSUSED*/
Notify_value
my_wait3(tty, pid, status, rusage)
Tty tty;
int pid;
union wait *status;
struct rusage *rusage;
{
X extern Panel_item edit_item;
X Textsw textsw = (Textsw)window_get(tty, WIN_CLIENT_DATA);
X char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
X int i = 0;
X
X if (WIFSTOPPED(*status)) {
X kill(pid, SIGCONT);
X return (NOTIFY_IGNORED);
X }
X if (pid != exec_pid || exec_pid <= 0) /* if the editor didn't die, return */
X return NOTIFY_DONE;
X /* editor died -- reset exec_pid so no one thinks we're running */
X exec_pid = 0;
X (void) window_set(tty, TTY_ARGV, TTY_ARGV_DO_NOT_FORK, NULL);
X wprint("Editor done.\n");
X (void) window_set(tty_sw, WIN_SHOW, FALSE, NULL);
#ifdef SUN_4_0 /* SunOS 4.0+ */
X (void) window_set(textsw,
X WIN_SHOW, TRUE,
X TEXTSW_FILE_CONTENTS, file,
X NULL);
#else /* SUN_4_0 */
X textsw_load_file(textsw, file, 1, 0, 0);
X textsw_set(textsw, WIN_SHOW, TRUE, NULL);
#endif /* SUN_4_0 */
X textsw_normalize_view(textsw, (Textsw_index)0);
X (void) unlink(file);
X set_comp_items(panel_get(edit_item, PANEL_PARENT_PANEL));
X
X return NOTIFY_DONE;
}
X
tool_edit_letter(textsw, argv)
Textsw textsw;
char **argv;
{
X Rect *msg_rect = (Rect *)window_get(textsw, WIN_RECT);
X
X wprint("Starting \"%s\"...\n", *argv);
#ifdef SUN_4_0
X window_set(textsw, WIN_SHOW, FALSE, NULL);
#else /* SUN_4_0 */
X textsw_set(textsw, WIN_SHOW, FALSE, NULL);
#endif /* SUN_4_0 */
X ttysw_output(tty_sw, "\f", 1); /* clear screen */
X (void) window_set(tty_sw,
X WIN_RECT, msg_rect,
X TTY_ARGV, argv,
X WIN_SHOW, TRUE,
X NULL);
X if ((exec_pid = (int) window_get(tty_sw, TTY_PID)) == -1) {
X error("Couldn't execute %s", *argv);
X return -1;
X }
X notify_set_wait3_func(tty_sw, my_wait3, exec_pid);
X Debug("tty pid = %d\n", exec_pid);
X return 0;
}
#endif /* SUNTOOL */
X
execute(argv)
char **argv;
{
#ifdef SYSV
X int status;
#else
X union wait status;
#endif /* SYSV */
#ifdef SIGCONT
X SIGRET (*oldstop)(), (*oldcont)();
#endif /* SIGCONT */
X int pid;
X SIGRET (*oldint)(), (*oldquit)();
X
X oldint = signal(SIGINT, SIG_IGN);
X oldquit = signal(SIGQUIT, SIG_IGN);
#ifdef SIGCONT
X oldstop = signal(SIGTSTP, SIG_DFL);
X oldcont = signal(SIGCONT, SIG_DFL);
#endif /* SIGCONT */
X turnon(glob_flags, IGN_SIGS);
X
X echo_on();
X if (!setjmp(execjbuf)) {
X if ((exec_pid = vfork()) == 0) {
X (void) signal(SIGINT, SIG_DFL);
X (void) signal(SIGQUIT, SIG_DFL);
X (void) signal(SIGPIPE, SIG_DFL);
X (void) closefileds(3); /* close all descriptors above 2 */
X execvp(*argv, argv);
X if (errno == ENOENT)
X print("%s: command not found.\n", *argv);
X else
X error(*argv);
X _exit(-1);
X }
X /* Parent's got to do something; sigchldcatcher may also be waiting.
X * This loop will usually get broken by the longjmp() (except tool),
X * but in certain circumstances sigchldcatcher isn't yet active.
X */
X while ((pid = wait(&status)) != -1 && pid != exec_pid)
X Debug("The exec loop caught a signal? (pid = %d)\n", pid);
X }
X /* reset our ttymodes */
X echo_off();
X (void) signal(SIGINT, oldint);
X (void) signal(SIGQUIT, oldquit);
#ifdef SIGCONT
X (void) signal(SIGTSTP, oldstop);
X (void) signal(SIGCONT, oldcont);
#endif /* SIGCONT */
X turnoff(glob_flags, IGN_SIGS);
}
X
SIGRET
sigchldcatcher()
{
#ifdef SYSV
X int status;
#else
X union wait status;
#endif /* SYSV */
X int pid;
X
#ifdef BSD
X while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
X Debug("%d died...\n", pid);
X if (pid == exec_pid)
X break;
X }
#else
#ifndef SYSV
X while ((pid = wait2(&status, WNOHANG)) > 0 && pid != exec_pid)
X Debug("%d died...\n", pid);
#else /* SYSV */
X while ((pid = wait((int *)0)) > 0 && pid != exec_pid)
X Debug("%d died...\n", pid);
#endif /* SYSV */
#endif /* BSD */
X if (pid == exec_pid && pid > 0) {
X exec_pid = 0;
X longjmp(execjbuf, 1);
X }
}
SHAR_EOF
chmod 0644 execute.c ||
echo 'restore of execute.c failed'
Wc_c="`wc -c < 'execute.c'`"
test 4196 -eq "$Wc_c" ||
echo 'execute.c: original size 4196, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= expr.c ==============
if test -f 'expr.c' -a X"$1" != X"-c"; then
echo 'x - skipping expr.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting expr.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'expr.c' &&
/* @(#)expr.c 2.3 (c) copyright 10/15/86 (Dan Heller) */
X
#include "mush.h"
X
char *eval_expr();
X
/* Parse a string (p) to interpret numbers and ranges of numbers (n-m)
X * delimited by whitespace or comma's. Set msg_list bitfields using
X * macros in mush.h.
X * Return the address of the end of whatever we parsed (in case there's
X * more that the calling routine cares to deal with).
X * Finally, remember that user specifies one more than actual message number
X */
char *
do_range(p, list1)
register char *p, *list1;
{
X register int num1 = -1, num2 = -1, except = 0;
X register char *p2;
X char list2[MAXMSGS_BITS];
X
X if (!p)
X return "";
X while (*p) {
X if (isdigit(*p) || *p == '$' || *p == '.' || *p == '^') {
X if (isdigit(*p)) {
X char c;
X p2 = p;
X skipdigits(0); /* find the end of the digits */
X c = *p, *p = 0; /* temporarily plug a null */
X if (!(num2 = chk_msg(p2))) {
X clear_msg_list(list1);
X return NULL;
X }
X *p = c;
X } else if (*p == '$')
X p++, num2 = msg_cnt;
X else if (*p == '.')
X p++, num2 = current_msg+1;
X else if (*p == '^')
X p++, num2 = 1;
X if (except)
X unset_msg_bit(list1, num2-1);
X else
X set_msg_bit(list1, num2-1);
X if (num1 >= 0) {
X if (num1 > num2) {
X print("syntax error: range sequence order reversed.\n");
X clear_msg_list(list1);
X return NULL;
X }
X while (++num1 < num2)
X if (except)
X unset_msg_bit(list1, num1-1);
X else
X set_msg_bit(list1, num1-1);
X num1 = num2 = -1;
X }
X }
X /* expressions to evaluate start with a `
X * p2 points to first char passed the last char parsed.
X */
X if (*p == '`') {
X clear_msg_list(list2);
X if (!(p = eval_expr(p, list2))) {
X clear_msg_list(list1);
X return NULL;
X } else {
X if (except)
X bitput(list2, list1, msg_cnt, &=~); /* MACRO */
X else
X bitput(list2, list1, msg_cnt, |=); /* MACRO */
X }
X }
X /* NOT operator: `* {5}' (everything except for 5)
X * `4-16 {8-10}' (4 thru 16 except for 8,9,10)
X */
X if (*p == '{' || *p == '}') {
X if (*p == '{' && (except || num1 >= 0))
X break;
X if (*p == '}' && !except) {
X print("syntax error: missing {\n"); /* } */
X break;
X }
X except = !except;
X } else if (*p == '-')
X if (num1 >= 0 || num2 < 0
X || !index(" \t{},.*`$", *(p+1)) && !isdigit(*(p+1)))
X break;
X else
X num1 = num2;
X else if (*p == ',' || *p == '*') {
X if (num1 >= 0)
X break;
X else if (*p == '*') {
X if (except)
X clear_msg_list(list1);
X else
X for (num1 = 0; num1 < msg_cnt; num1++)
X set_msg_bit(list1, num1);
X num1 = -1;
X }
X } else if (!index(" \t`", *p))
X break;
X if (*p)
X skipspaces(1); /* don't make user type stuff squished together */
X }
X if (num1 >= 0 || except) {
X if (except)
X /* { */ print("syntax error: unmatched }\n");
X else
X print("syntax error: unfinished range\n");
X clear_msg_list(list1);
X return NULL;
X }
X return p;
}
X
/*
X * convert a message list to an ascii string.
X */
void
list_to_str(list, str)
char list[], *str;
{
X int n, m = -1;
X
X for (n = 0; n < msg_cnt; n++) {
X if (msg_bit(list, n)) {
X if (m == -1)
X str += strlen(sprintf(str, "%d", (m = n) + 1 ));
X continue;
X }
X if (m == -1)
X continue;
X if (n - m > 2)
X str += strlen(sprintf(str, "-%d", n));
X else if (n - m == 2)
X str += strlen(sprintf(str, " %d", n));
X *str++ = ' ';
X m = -1;
X }
X if (m > -1 && m != n - 1) {
X if (n - m > 2)
X *str++ = '-';
X else
X *str++ = ' ';
X str += Strcpy(str, itoa(msg_cnt));
X }
X *str = 0;
}
X
/* evaluate expressions:
X * mail> delete `pick -f root` deletes all messages from root.
X * mail> save * {`pick -s "Re:"`} save all message that don't have "Re:"
X * in the subject header.
X * mail> save `pick -x -s "Re:"` same
X * args as follows:
X * p should point to the first ` -- check for it.
X * on tells whether to turn bits on or off if messages match.
SHAR_EOF
true || echo 'restore of expr.c failed'
fi
echo 'End of part 7'
echo 'File expr.c is continued in part 8'
echo 8 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.