home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i100: Elm mail system, release 2.2, Part21/22
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: dsinc!syd@uunet.UU.NET (Syd Weinstein)
- Posting-number: Volume 18, Issue 100
- Archive-name: elm2.2/part21
-
- #!/bin/sh
- # this is part 21 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file src/showmsg_c.c continued
- #
- CurArch=21
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file src/showmsg_c.c"
- sed 's/^X//' << 'SHAR_EOF' >> src/showmsg_c.c
- X#else
- X store_msg("Can't scan for calendar entries!");
- X#endif
- X break;
- X
- X case '%' : put_cmd_name("Display return address", TRUE);
- X get_return(msg_line, current-1);
- X break;
- X
- X case 'b' : put_cmd_name("Bounce message", TRUE);
- X remail();
- X break;
- X
- X case 'd' : delete_msg(TRUE, FALSE); /* really delete it, silent */
- X if (! resolve_mode)
- X store_msg("Message marked for deletion.");
- X else
- X goto next_undel_msg;
- X break;
- X
- X case 'f' : put_cmd_name("Forward message", TRUE);
- X if(forward()) put_border();
- X break;
- X
- X case 'g' : put_cmd_name("Group reply", TRUE);
- X (void) reply_to_everyone();
- X break;
- X
- X case 'h' : screen_mangled = 0;
- X if (filter) {
- X filter = 0;
- X intbuf = show_msg(current);
- X filter = 1;
- X return(intbuf);
- X } else
- X return(show_msg(current));
- X
- X case 'q' :
- X case 'i' : (void) get_page(current);
- X clear_error(); /* zero out pending msg */
- X if (cursor_control)
- X transmit_functions(ON);
- X screen_mangled = 0;
- X return(0); /* avoid <return> looping */
- X
- Xnext_undel_msg : /* a target for resolve mode actions */
- X
- X case ' ' :
- X case 'j' :
- X case 'n' : screen_mangled = 0;
- X if((i=next_message(current-1, TRUE)) != -1)
- X return(show_msg(current = i+1));
- X else return(0);
- X
- Xnext_msg:
- X case 'J' : screen_mangled = 0;
- X if((i=next_message(current-1, FALSE)) != -1)
- X return(show_msg(current = i+1));
- X else return(0);
- X
- Xprev_undel_msg:
- X case 'k' : screen_mangled = 0;
- X if((i=prev_message(current-1, TRUE)) != -1)
- X return(show_msg(current = i+1));
- X else return(0);
- X
- X case 'K' : screen_mangled = 0;
- X if((i=prev_message(current-1, FALSE)) != -1)
- X return(show_msg(current = i+1));
- X else return(0);
- X
- X case 'm' : put_cmd_name("Mail message", TRUE);
- X if(sendmsg("","","", TRUE, allow_forms, FALSE))
- X put_border();
- X break;
- X
- X case 'p' : put_cmd_name("Print message", FALSE);
- X print_msg();
- X store_msg("Queued for printing.");
- X break;
- X
- X case 'r' : put_cmd_name("Reply to message", TRUE);
- X if(reply()) put_border();
- X break;
- X
- X case '>' :
- X case 'C' :
- X case 's' : put_cmd_name((command != 'C' ? "Save" : "Copy"), TRUE);
- X (void) save(&intbuf, TRUE, (command != 'C'));
- X if (resolve_mode && command != 'C')
- X goto next_undel_msg;
- X break;
- X
- X case 't' : istagged=tag_message(FALSE);
- X if(istagged)
- X store_msg("Message tagged.");
- X else
- X store_msg("Message untagged.");
- X break;
- X
- X case 'u' : undelete_msg(FALSE); /* undelete it, silently */
- X if (! resolve_mode)
- X store_msg("Message undeleted.");
- X else {
- X/******************************************************************************
- X ** We're special casing the U)ndelete command here *not* to move to the next
- X ** undeleted message ; instead it'll blindly move to the next message in the
- X ** list. See 'elm.c' and the command by "case 'u'" for further information.
- X ** The old code was:
- X goto next_undel_msg;
- X*******************************************************************************/
- X goto next_msg;
- X }
- X break;
- X
- X case 'x' : fflush(stdout); leave();
- X
- X case ctrl('J'):
- X case ctrl('M'): screen_mangled = 0;
- X return(show_msg(current));
- X
- X
- X case ESCAPE : if (cursor_control) {
- X
- X key_offset = 1;
- X
- X ch = ReadCh();
- X
- X if (ch == ESCAPE)
- X ch = ReadCh();
- X
- X if ( ch == '[' || ch == 'O')
- X {
- X ch = ReadCh();
- X key_offset++;
- X }
- X
- X if (ch == up[key_offset])
- X goto prev_undel_msg;
- X else if (ch == down[key_offset])
- X goto next_undel_msg;
- X else {
- X screen_mangled = 0;
- X return(0);
- X }
- X }
- X else /* Eat 2 chars for escape codes */
- X {
- X ch = ReadCh();
- X ch = ReadCh();
- X putchar((char) 007);
- X fflush(stdout);
- X screen_mangled = 0;
- X return(0);
- X }
- X
- X default : putchar((char) 007); /* BEEP! */
- X }
- X
- X /* display prompt */
- X if (screen_mangled) {
- X /* clear what was left over from previous command
- X * and display last generated message.
- X */
- X put_prompt();
- X CleartoEOS();
- X put_help();
- X Centerline(LINES, msg_line);
- X MoveCursor(LINES-3, POST_PROMPT_COL);
- X } else {
- X /* display bottom line prompt with last generated message */
- X MoveCursor(LINES, 0);
- X CleartoEOS();
- X StartBold();
- X Write_to_screen("%s Command ('i' to return to index): ",
- X 1, msg_line);
- X EndBold();
- X }
- X *msg_line = '\0'; /* null last generated message */
- X
- X command = GetPrompt(); /* get next command from user */
- X }
- X}
- X
- Xput_cmd_name(command, will_mangle)
- Xchar *command;
- Xint will_mangle;
- X{
- X
- X /* If screen is or will be mangled display the command name
- X * and erase the bottom of the screen.
- X * But first if the border line hasn't yet been drawn, draw it.
- X */
- X if(will_mangle && !screen_mangled) {
- X build_bottom();
- X screen_mangled = TRUE;
- X }
- X if(screen_mangled) {
- X PutLine0(LINES-3, POST_PROMPT_COL, command);
- X CleartoEOS();
- X }
- X}
- X
- Xput_border()
- X{
- X PutLine0(LINES-4, 0,
- X"--------------------------------------------------------------------------\n");
- X}
- X
- Xbuild_bottom()
- X{
- X MoveCursor(LINES-4, 0);
- X CleartoEOS();
- X put_border();
- X put_prompt();
- X put_help();
- X}
- SHAR_EOF
- echo "File src/showmsg_c.c is complete"
- chmod 0444 src/showmsg_c.c || echo "restore of src/showmsg_c.c fails"
- echo "x - extracting src/signals.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/signals.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: signals.c,v 2.5 89/03/25 21:47:23 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.5 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: signals.c,v $
- X * Revision 2.5 89/03/25 21:47:23 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** This set of routines traps various signals and informs the
- X user of the error, leaving the program in a nice, graceful
- X manner.
- X
- X**/
- X
- X#include "headers.h"
- X#include <signal.h>
- X
- Xextern int pipe_abort; /* set to TRUE if receive SIGPIPE */
- X
- Xquit_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGQUIT **\n\n\n\n"));
- X leave();
- X}
- X
- Xhup_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGHUP **\n\n\n\n"));
- X leave();
- X}
- X
- Xterm_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGTERM **\n\n\n\n"));
- X leave();
- X}
- X
- Xill_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGILL **\n\n\n\n"));
- X PutLine0(LINES, 0, "\n\nIllegal Instruction signal!\n\n");
- X emergency_exit();
- X}
- X
- Xfpe_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGFPE **\n\n\n\n"));
- X PutLine0(LINES, 0,"\n\nFloating Point Exception signal!\n\n");
- X emergency_exit();
- X}
- X
- Xbus_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGBUS **\n\n\n\n"));
- X PutLine0(LINES, 0,"\n\nBus Error signal!\n\n");
- X emergency_exit();
- X}
- X
- Xsegv_signal()
- X{
- X dprint(1, (debugfile,"\n\n** Received SIGSEGV **\n\n\n\n"));
- X PutLine0(LINES, 0,"\n\nSegment Violation signal!\n\n");
- X emergency_exit();
- X}
- X
- X#ifdef VOIDSIG
- Xvoid alarm_signal()
- X#else
- Xint alarm_signal()
- X#endif
- X{
- X /** silently process alarm signal for timeouts... **/
- X
- X#ifdef VOIDSIG
- X void alarm_signal();
- X#else
- X int alarm_signal();
- X#endif
- X
- X signal(SIGALRM, alarm_signal);
- X}
- X
- X#ifdef VOIDSIG
- Xvoid pipe_signal()
- X#else
- Xint pipe_signal()
- X#endif
- X{
- X /** silently process pipe signal... **/
- X
- X#ifdef VOIDSIG
- X void pipe_signal();
- X#else
- X int pipe_signal();
- X#endif
- X
- X dprint(2, (debugfile, "*** received SIGPIPE ***\n\n"));
- X
- X pipe_abort = TRUE; /* internal signal ... wheeee! */
- X
- X signal(SIGPIPE, pipe_signal);
- X}
- X
- X#ifdef SIGTSTP
- Xint was_in_raw_state;
- X
- X#ifdef VOIDSIG
- Xvoid sig_user_stop()
- X#else
- Xint sig_user_stop()
- X#endif
- X{
- X /* This is called when the user presses a ^Z to stop the
- X process within BSD
- X */
- X if (signal(SIGTSTP, SIG_DFL) != SIG_DFL)
- X signal(SIGTSTP, SIG_DFL);
- X
- X was_in_raw_state = RawState();
- X Raw(OFF); /* turn it off regardless */
- X
- X printf("\n\nStopped. Use \"fg\" to return to ELM\n\n");
- X
- X kill(0, SIGSTOP);
- X}
- X
- Xsig_return_from_user_stop()
- X{
- X /** this is called when returning from a ^Z stop **/
- X
- X#ifdef VOIDSIG
- X void sig_user_stop();
- X#else
- X int sig_user_stop();
- X#endif
- X
- X if (signal(SIGTSTP, sig_user_stop) == SIG_DFL)
- X signal(SIGTSTP, sig_user_stop);
- X
- X printf(
- X "\nBack in ELM. (You might need to explicitly request a redraw.)\n\n");
- X
- X if (was_in_raw_state)
- X Raw(ON);
- X}
- X#endif
- SHAR_EOF
- chmod 0444 src/signals.c || echo "restore of src/signals.c fails"
- echo "x - extracting src/softkeys.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/softkeys.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: softkeys.c,v 2.8 89/03/25 21:47:25 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.8 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: softkeys.c,v $
- X * Revision 2.8 89/03/25 21:47:25 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X
- X#include "headers.h"
- X
- Xdefine_softkeys(level)
- Xint level;
- X{
- X if (! hp_softkeys) return;
- X
- X if (level == MAIN) {
- X
- X define_key(f1, " Display Msg", "\r");
- X define_key(f2, " Mail Msg", "m");
- X define_key(f3, " Reply to Msg", "r");
- X
- X if (user_level == 0) {
- X define_key(f4, " Save Msg", "s");
- X define_key(f5, " Delete Msg", "d");
- X define_key(f6, "Undelete Msg", "u");
- X }
- X else {
- X define_key(f4, " Change Folder", "c");
- X define_key(f5, " Save Msg", "s");
- X define_key(f6, " Delete/Undelete", "^");
- X }
- X
- X define_key(f7, " Print Msg", "p");
- X define_key(f8, " Quit ELM", "q");
- X }
- X else if (level == ALIAS) {
- X define_key(f1, " Alias Current", "a");
- X define_key(f2, " Check Person", "p");
- X define_key(f3, " Check System", "s");
- X define_key(f4, " Make Alias", "m");
- X clear_key(f5);
- X clear_key(f6);
- X clear_key(f7);
- X define_key(f8, " Return to ELM", "r");
- X }
- X else if (level == YESNO) {
- X define_key(f1, " Yes", "y");
- X clear_key(f2);
- X clear_key(f3);
- X clear_key(f4);
- X clear_key(f5);
- X clear_key(f6);
- X clear_key(f7);
- X define_key(f8, " No", "n");
- X }
- X else if (level == READ) {
- X define_key(f1, " Next Page ", " ");
- X clear_key(f2);
- X define_key(f3, " Next Msg ", "j");
- X define_key(f4, " Prev Msg ", "k");
- X define_key(f5, " Reply to Msg ", "r");
- X define_key(f6, " Delete Msg ", "d");
- X define_key(f7, " Send Msg ", "m");
- X define_key(f8, " Return to ELM ", "q");
- X }
- X else if (level == CHANGE) {
- X define_key(f1, " Mail Directry", "=/");
- X define_key(f2, " Home Directry", "~/");
- X clear_key(f3);
- X define_key(f4, "Incoming Mailbox", "!\n");
- X define_key(f5, "\"Received\" Folder", ">\n");
- X define_key(f6, "\"Sent\" Folder ", "<\n");
- X clear_key(f7);
- X define_key(f8, " Cancel", "\n");
- X }
- X
- X softkeys_on();
- X}
- X
- Xdefine_key(key, display, send)
- Xint key;
- Xchar *display, *send;
- X{
- X
- X char buffer[30];
- X
- X sprintf(buffer,"%s%s", display, send);
- X
- X fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
- X strlen(display), strlen(send), buffer);
- X fflush(stdout);
- X}
- X
- Xsoftkeys_on()
- X{
- X /* enable (esc&s1A) turn on softkeys (esc&jB) and turn on MENU
- X and USER/SYSTEM options. */
- X
- X if (hp_softkeys) {
- X fprintf(stderr, "%c&s1A%c&jB%c&jR", ESCAPE, ESCAPE, ESCAPE);
- X fflush(stdout);
- X }
- X
- X}
- X
- Xsoftkeys_off()
- X{
- X /* turn off softkeys (esc&j@) */
- X
- X if (hp_softkeys) {
- X fprintf(stderr, "%c&s0A%c&j@", ESCAPE, ESCAPE);
- X fflush(stdout);
- X }
- X}
- X
- Xclear_key(key)
- X{
- X /** set a key to nothing... **/
- X
- X if (hp_softkeys)
- X define_key(key, " ", "");
- X}
- SHAR_EOF
- chmod 0444 src/softkeys.c || echo "restore of src/softkeys.c fails"
- echo "x - extracting src/sort.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/sort.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: sort.c,v 2.7 89/03/25 21:47:26 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.7 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: sort.c,v $
- X * Revision 2.7 89/03/25 21:47:26 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** Sort folder header table by the field specified in the global
- X variable "sortby"...if we're sorting by something other than
- X the default SENT_DATE, also put some sort of indicator on the
- X screen.
- X
- X**/
- X
- X#include "headers.h"
- X
- Xchar *sort_name(), *skip_re();
- Xvoid qsort();
- X
- Xsort_mailbox(entries, visible)
- Xint entries, visible;
- X{
- X /** Sort the header_table definitions... If 'visible', then
- X put the status lines etc **/
- X
- X int last_index = -1;
- X int compare_headers(); /* for sorting */
- X
- X dprint(2, (debugfile, "\n** sorting folder by %s **\n\n",
- X sort_name(FULL)));
- X
- X /* Don't get last_index if no entries or no current. */
- X /* There would be no current if we are sorting a new mail file. */
- X if (entries > 0 && current > 0)
- X last_index = headers[current-1]->index_number;
- X
- X if (entries > 30 && visible)
- X error1("Sorting messages by %s...", sort_name(FULL));
- X
- X qsort(headers, (unsigned) entries, sizeof (struct header_rec *),
- X compare_headers);
- X
- X if (last_index > -1)
- X find_old_current(last_index);
- X
- X clear_error();
- X}
- X
- Xint
- Xcompare_headers(p1, p2)
- Xstruct header_rec **p1, **p2;
- X{
- X /** compare two headers according to the sortby value.
- X
- X Sent Date uses a routine to compare two dates,
- X Received date is keyed on the file offsets (think about it)
- X Sender uses the truncated from line, same as "build headers",
- X and size and subject are trivially obvious!!
- X (actually, subject has been modified to ignore any leading
- X patterns [rR][eE]*:[ \t] so that replies to messages are
- X sorted with the message (though a reply will always sort to
- X be 'greater' than the basenote)
- X **/
- X
- X char from1[SLEN], from2[SLEN]; /* sorting buffers... */
- X struct header_rec *first, *second;
- X int ret;
- X
- X first = *p1;
- X second = *p2;
- X
- X switch (abs(sortby)) {
- X case SENT_DATE:
- X ret = compare_dates(first, second);
- X break;
- X
- X case RECEIVED_DATE:
- X ret = compare_parsed_dates(first->received, second->received);
- X break;
- X
- X case SENDER:
- X tail_of(first->from, from1, first->to);
- X tail_of(second->from, from2, second->to);
- X ret = strcmp(from1, from2);
- X break;
- X
- X case SIZE:
- X ret = (first->lines - second->lines);
- X break;
- X
- X case MAILBOX_ORDER:
- X ret = (first->index_number - second->index_number);
- X break;
- X
- X case SUBJECT:
- X /* need some extra work 'cause of STATIC buffers */
- X strcpy(from1, skip_re(shift_lower(first->subject)));
- X ret = strcmp(from1, skip_re(shift_lower(second->subject)));
- X break;
- X
- X case STATUS:
- X ret = (first->status - second->status);
- X break;
- X
- X default:
- X /* never get this! */
- X ret = 0;
- X break;
- X }
- X
- X if (sortby < 0)
- X ret = -ret;
- X
- X return ret;
- X}
- X
- Xchar *sort_name(type)
- Xint type;
- X{
- X /** return the name of the current sort option...
- X type can be "FULL", "SHORT" or "PAD"
- X **/
- X int pad, abr;
- X
- X pad = (type == PAD);
- X abr = (type == SHORT);
- X
- X if (sortby < 0) {
- X switch (- sortby) {
- X case SENT_DATE : return(
- X pad? "Reverse Date Mail Sent " :
- X abr? "Reverse-Sent" :
- X "Reverse Date Mail Sent");
- X case RECEIVED_DATE: return(
- X abr? "Reverse-Received":
- X "Reverse Date Mail Rec'vd" );
- X
- X case MAILBOX_ORDER: return(
- X pad? "Reverse Mailbox Order " :
- X abr? "Reverse-Mailbox":
- X "Reverse Mailbox Order");
- X
- X case SENDER : return(
- X pad? "Reverse Message Sender " :
- X abr? "Reverse-From":
- X "Reverse Message Sender");
- X case SIZE : return(
- X abr? "Reverse-Lines" :
- X "Reverse Lines in Message");
- X case SUBJECT : return(
- X pad? "Reverse Message Subject " :
- X abr? "Reverse-Subject" :
- X "Reverse Message Subject");
- X case STATUS : return(
- X pad? "Reverse Message Status " :
- X abr? "Reverse-Status":
- X "Reverse Message Status");
- X }
- X }
- X else {
- X switch (sortby) {
- X case SENT_DATE : return(
- X pad? "Date Mail Sent " :
- X abr? "Sent" :
- X "Date Mail Sent");
- X case RECEIVED_DATE: return(
- X pad? "Date Mail Rec'vd " :
- X abr? "Received" :
- X "Date Mail Rec'vd");
- X case MAILBOX_ORDER: return(
- X pad? "Mailbox Order " :
- X abr? "Mailbox" :
- X "Mailbox Order");
- X case SENDER : return(
- X pad? "Message Sender " :
- X abr? "From" :
- X "Message Sender");
- X case SIZE : return(
- X pad? "Lines in Message " :
- X abr? "Lines" :
- X "Lines in Message");
- X case SUBJECT : return(
- X pad? "Message Subject " :
- X abr? "Subject" :
- X "Message Subject");
- X case STATUS : return(
- X pad? "Message Status " :
- X abr? "Status" :
- X "Message Status");
- X }
- X }
- X
- X return("*UNKNOWN-SORT-PARAMETER*");
- X}
- X
- Xfind_old_current(iindex)
- Xint iindex;
- X{
- X /** Set current to the message that has "index" as it's
- X index number. This is to track the current message
- X when we resync... **/
- X
- X register int i;
- X
- X dprint(4, (debugfile, "find-old-current(%d)\n", iindex));
- X
- X for (i = 0; i < message_count; i++)
- X if (headers[i]->index_number == iindex) {
- X current = i+1;
- X dprint(4, (debugfile, "\tset current to %d!\n", current));
- X return;
- X }
- X
- X dprint(4, (debugfile,
- X "\tcouldn't find current index. Current left as %d\n",
- X current));
- X return; /* can't be found. Leave it alone, then */
- X}
- X
- Xchar *skip_re(string)
- Xchar *string;
- X{
- X /** this routine returns the given string minus any sort of
- X "re:" prefix. specifically, it looks for, and will
- X remove, any of the pattern:
- X
- X ( [Rr][Ee][^:]:[ ] ) *
- X
- X If it doesn't find a ':' in the line it will return it
- X intact, just in case!
- X **/
- X
- X static char buffer[SLEN];
- X register int i=0;
- X
- X while (whitespace(string[i])) i++;
- X
- X do {
- X if (string[i] == '\0') return( (char *) string); /* forget it */
- X
- X if (string[i] != 'r' || string[i+1] != 'e')
- X return( (char *) string); /* ditto */
- X
- X i += 2; /* skip the "re" */
- X
- X while (string[i] != ':')
- X if (string[i] == '\0')
- X return( (char *) string); /* no colon in string! */
- X else
- X i++;
- X
- X /* now we've gotten to the colon, skip to the next non-whitespace */
- X
- X i++; /* past the colon */
- X
- X while (whitespace(string[i])) i++;
- X
- X } while (string[i] == 'r' && string[i+1] == 'e');
- X
- X /* and now copy it into the buffer and sent it along... */
- X
- X strcpy(buffer, (char *) string + i);
- X
- X return( (char *) buffer);
- X}
- SHAR_EOF
- chmod 0444 src/sort.c || echo "restore of src/sort.c fails"
- echo "x - extracting src/string2.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/string2.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: string2.c,v 2.3 89/03/25 21:47:28 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.3 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: string2.c,v $
- X * Revision 2.3 89/03/25 21:47:28 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains string functions that are shared throughout the
- X various ELM utilities...
- X
- X**/
- X
- X#ifndef TRUE
- X#define TRUE 1
- X#define FALSE 0
- X#endif
- X
- X#define whitespace(c) (c == ' ' || c == '\t')
- X
- Xint
- Xin_string(buffer, pattern)
- Xchar *buffer, *pattern;
- X{
- X /** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/
- X
- X register int i = 0, j = 0;
- X
- X while (buffer[i] != '\0') {
- X while (buffer[i++] == pattern[j++])
- X if (pattern[j] == '\0')
- X return(TRUE);
- X i = i - j + 1;
- X j = 0;
- X }
- X return(FALSE);
- X}
- X
- Xint
- Xchloc(string, ch)
- Xchar *string, ch;
- X{
- X /** returns the index of ch in string, or -1 if not in string **/
- X register int i;
- X
- X for (i=0; i<strlen(string); i++)
- X if (string[i] == ch) return(i);
- X return(-1);
- X}
- X
- Xint
- Xoccurances_of(ch, string)
- Xchar ch, *string;
- X{
- X /** returns the number of occurances of 'ch' in string 'string' **/
- X
- X register int count = 0, i;
- X
- X for (i=0; i<strlen(string); i++)
- X if (string[i] == ch) count++;
- X
- X return(count);
- X}
- X
- Xremove_possible_trailing_spaces(string)
- Xchar *string;
- X{
- X /** an incredibly simple routine that will read backwards through
- X a string and remove all trailing whitespace.
- X **/
- X
- X register int i;
- X
- X for (i=strlen(string)-1; whitespace(string[i]); i--)
- X /** spin backwards **/
- X
- X string[i+1] = '\0'; /* note that even in the worst case when there
- X are no trailing spaces at all, we'll simply
- X end up replacing the existing '\0' with
- X another one! No worries, as M.G. would say
- X */
- X}
- SHAR_EOF
- chmod 0444 src/string2.c || echo "restore of src/string2.c fails"
- echo "x - extracting src/strings.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/strings.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: strings.c,v 2.10 89/03/25 21:47:29 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.10 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: strings.c,v $
- X * Revision 2.10 89/03/25 21:47:29 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains all the string oriented functions for the
- X ELM Mailer, and lots of other generally useful string functions!
- X
- X For BSD systems, this file also includes the function "tolower"
- X to translate the given character from upper case to lower case.
- X
- X**/
- X
- X#include "headers.h"
- X#include <ctype.h>
- X
- X#ifdef BSD
- X#undef tolower
- X#undef toupper
- X#endif
- X
- X/** forward declarations **/
- X
- Xchar *format_long(), *strip_commas(), *tail_of_string(), *shift_lower(),
- X *get_token(), *strip_parens(), *argv_zero(), *strcpy(), *strncpy();
- X
- X
- Xcopy_sans_escape(dest, source, len)
- Xchar *dest, *source;
- Xint len;
- X{
- X /** this performs the same function that strncpy() does, but
- X also will translate any escape character to a printable
- X format (e.g. ^(char value + 32))
- X **/
- X
- X register int i = 0, j = 0;
- X
- X while (i < len && source[i] != '\0') {
- X if (iscntrl(source[i]) && source[i] != '\t') {
- X dest[j++] = '^';
- X dest[j++] = source[i++] + 'A' - 1;
- X }
- X else
- X dest[j++] = source[i++];
- X }
- X
- X dest[j] = '\0';
- X}
- X
- Xint
- Xtail_of(from, buffer, to)
- Xchar *from, *buffer, *to;
- X{
- X /** Return last two words of 'from'. This is to allow
- X painless display of long return addresses as simply the
- X machine!username.
- X Or if the first word of the 'from' address is username or
- X full_username and 'to' is not NULL, then use the 'to' line
- X instead of the 'from' line.
- X If the 'to' line is used, return 1, else return 0.
- X
- X Also modified to know about X.400 addresses (sigh) and
- X that when we ask for the tail of an address similar to
- X a%b@c we want to get back a@b ...
- X **/
- X
- X /** Note: '!' delimits Usenet nodes, '@' delimits ARPA nodes,
- X ':' delimits CSNet & Bitnet nodes, '%' delimits multi-
- X stage ARPA hops, and '/' delimits X.400 addresses...
- X (it is fortunate that the ASCII character set only has
- X so many metacharacters, as I think we're probably using
- X them all!!) **/
- X
- X register int loc, i = 0, cnt = 0, using_to = 0;
- X
- X#ifndef INTERNET
- X
- X /** let's see if we have an address appropriate for hacking:
- X what this actually does is remove the spuriously added
- X local bogus Internet header if we have one and the message
- X has some sort of UUCP component too...
- X **/
- X
- X sprintf(buffer, "@%s%s", hostname, hostdomain);
- X if (chloc(from,'!') != -1 && in_string(from, buffer))
- X from[strlen(from)-strlen(buffer)] = '\0';
- X
- X#endif
- X
- X for (loc = strlen(from)-1; loc >= 0 && cnt < 2; loc--) {
- X if (from[loc] == BANG || from[loc] == AT_SIGN ||
- X from[loc] == COLON) cnt++;
- X if (cnt < 2) buffer[i++] = from[loc];
- X }
- X
- X buffer[i] = '\0';
- X
- X reverse(buffer);
- X
- X if ((strncmp(buffer, username, strlen(username)) == 0) ||
- X (strncmp(buffer, full_username, strlen(full_username)) == 0)) {
- X
- X /* This message is from the user, so use the "to" header instead
- X * if possible, to be more informative. Otherwise be nice and
- X * use full_username rather than the bare username even if
- X * we've only matched on the bare username.
- X */
- X
- X if(to && *to != '\0') {
- X tail_of(to, buffer, (char *)0);
- X using_to = 1;
- X } else
- X strcpy(buffer, full_username);
- X
- X } else { /* user%host@host? */
- X
- X /** The logic here is that we're going to use 'loc' as a handy
- X flag to indicate if we've hit a '%' or not. If we have,
- X we'll rewrite it as an '@' sign and then when we hit the
- X REAL at sign (we must have one) we'll simply replace it
- X with a NULL character, thereby ending the string there.
- X **/
- X
- X loc = 0;
- X
- X for (i=0; buffer[i] != '\0'; i++)
- X if (buffer[i] == '%') {
- X buffer[i] = AT_SIGN;
- X loc++;
- X }
- X else if (buffer[i] == AT_SIGN && loc)
- X buffer[i] = '\0';
- X }
- X return(using_to);
- X
- X}
- X
- Xchar *format_long(inbuff, init_len)
- Xchar *inbuff;
- Xint init_len;
- X{
- X /** Return buffer with \n\t sequences added at each point where it
- X would be more than 80 chars long. It only allows the breaks at
- X legal points (ie commas followed by white spaces). init-len is
- X the characters already on the first line... Changed so that if
- X this is called while mailing without the overhead of "elm", it'll
- X include "\r\n\t" instead.
- X Changed to use ',' as a separator and to REPLACE it after it's
- X found in the output stream...
- X **/
- X
- X static char ret_buffer[VERY_LONG_STRING];
- X register int iindex = 0, current_length = 0, depth=15, i;
- X char buffer[VERY_LONG_STRING];
- X char *word, *bufptr;
- X
- X strcpy(buffer, inbuff);
- X
- X bufptr = (char *) buffer;
- X
- X current_length = init_len + 2; /* for luck */
- X
- X while ((word = get_token(bufptr,",", depth)) != NULL) {
- X
- X /* first, decide what sort of separator we need, if any... */
- X
- X if (strlen(word) + current_length > 80) {
- X if (iindex > 0) {
- X ret_buffer[iindex++] = ','; /* close 'er up, doctor! */
- X ret_buffer[iindex++] = '\n';
- X ret_buffer[iindex++] = '\t';
- X }
- X
- X /* now add this pup! */
- X
- X for (i=(word[0] == ' '? 1:0); i<strlen(word); i++)
- X ret_buffer[iindex++] = word[i];
- X current_length = strlen(word) + 8; /* 8 = TAB */
- X }
- X
- X else { /* just add this address to the list.. */
- X
- X if (iindex > 0) {
- X ret_buffer[iindex++] = ','; /* comma added! */
- X ret_buffer[iindex++] = ' ';
- X current_length += 2;
- X }
- X for (i=(word[0] == ' '? 1:0); i<strlen(word); i++)
- X ret_buffer[iindex++] = word[i];
- X current_length += strlen(word);
- X }
- X
- X bufptr = NULL;
- X }
- X
- X ret_buffer[iindex] = '\0';
- X
- X return( (char *) ret_buffer);
- X}
- X
- Xchar *strip_commas(string)
- Xchar *string;
- X{
- X /** return string with all commas changed to spaces. This IS
- X destructive and will permanently change the input string.. **/
- X
- X register int i;
- X
- X for (i=0; i < strlen(string); i++)
- X if (string[i] == COMMA)
- X string[i] = SPACE;
- X
- X return( (char *) string);
- X}
- X
- Xchar *strip_parens(string)
- Xchar *string;
- X{
- X /** Return string with all parenthesized information removed.
- X This is a non-destructive algorithm... **/
- X
- X static char buffer[VERY_LONG_STRING];
- X register int i, depth = 0, buffer_index = 0;
- X
- X for (i=0; i < strlen(string); i++) {
- X if (string[i] == '(')
- X depth++;
- X else if (string[i] == ')')
- X depth--;
- X else if (depth == 0)
- X buffer[buffer_index++] = string[i];
- X }
- X
- X buffer[buffer_index] = '\0';
- X
- X return( (char *) buffer);
- X}
- X
- Xmove_left(string, chars)
- Xchar string[];
- Xint chars;
- X{
- X /** moves string chars characters to the left DESTRUCTIVELY **/
- X
- X register int i;
- X
- X /* chars--; /* index starting at zero! */
- X
- X for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
- X string[i-chars] = string[i];
- X
- X string[i-chars] = '\0';
- X}
- X
- Xremove_first_word(string)
- Xchar *string;
- X{ /** removes first word of string, ie up to first non-white space
- X following a white space! **/
- X
- X register int loc;
- X
- X for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
- X ;
- X
- X while (string[loc] == ' ' || string[loc] == '\t')
- X loc++;
- X
- X move_left(string, loc);
- X}
- X
- Xsplit_word(buffer, first, rest)
- Xchar *buffer, *first, *rest;
- X{
- X /** Rip the buffer into first word and rest of word, translating it
- X all to lower case as we go along..
- X **/
- X
- X register int i, j = 0;
- X
- X /** skip leading white space, just in case.. **/
- X
- X for (i=0; whitespace(buffer[i]); i++) ;
- X
- X /** now copy into 'first' until we hit white space or EOLN **/
- X
- X for (j=0; i < strlen(buffer) && ! whitespace(buffer[i]); ++i)
- X first[j++] = tolower(buffer[i]);
- X
- X first[j] = '\0';
- X
- X while (whitespace(buffer[i])) i++;
- X
- X for (j=0; i < strlen(buffer); i++)
- X rest[j++] = tolower(buffer[i]);
- X
- X rest[j] = '\0';
- X
- X return;
- X}
- X
- Xchar *tail_of_string(string, maxchars)
- Xchar *string;
- Xint maxchars;
- X{
- X /** Return a string that is the last 'maxchars' characters of the
- X given string. This is only used if the first word of the string
- X is longer than maxchars, else it will return what is given to
- X it...
- X **/
- X
- X static char buffer[SLEN];
- X register int iindex, i;
- X
- X for (iindex=0;! whitespace(string[iindex]) && iindex < strlen(string);
- X iindex++)
- X ;
- X
- X if (iindex < maxchars) {
- X strncpy(buffer, string, maxchars-2); /* word too short */
- X buffer[maxchars-2] = '.';
- X buffer[maxchars-1] = '.';
- X buffer[maxchars] = '.';
- X buffer[maxchars+1] = '\0';
- X }
- X else {
- X i = maxchars;
- X buffer[i--] = '\0';
- X while (i > 1)
- X buffer[i--] = string[iindex--];
- X buffer[2] = '.';
- X buffer[1] = '.';
- X buffer[0] = '.';
- X }
- X
- X return( (char *) buffer);
- X}
- X
- Xreverse(string)
- Xchar *string;
- X{
- X /** reverse string... pretty trivial routine, actually! **/
- X
- X char buffer[SLEN];
- X register int i, j = 0;
- X
- X for (i = strlen(string)-1; i >= 0; i--)
- X buffer[j++] = string[i];
- X
- X buffer[j] = '\0';
- X
- X strcpy(string, buffer);
- X}
- X
- Xint
- Xget_word(buffer, start, word)
- Xchar *buffer, *word;
- Xint start;
- X{
- X /** return next word in buffer, starting at 'start'.
- X delimiter is space or end-of-line. Returns the
- X location of the next word, or -1 if returning
- X the last word in the buffer. -2 indicates empty
- X buffer! **/
- X
- X register int loc = 0;
- X
- X while (buffer[start] == ' ' && buffer[start] != '\0')
- X start++;
- X
- X if (buffer[start] == '\0') return(-2); /* nothing IN buffer! */
- X
- X while (buffer[start] != ' ' && buffer[start] != '\0')
- X word[loc++] = buffer[start++];
- X
- X word[loc] = '\0';
- X return(start);
- X}
- X
- Xchar *shift_lower(string)
- Xchar *string;
- X{
- X /** return 'string' shifted to lower case. Do NOT touch the
- X actual string handed to us! **/
- X
- X static char buffer[SLEN];
- X register int i;
- X
- X for (i=0; i < strlen(string); i++)
- X if (isupper(string[i]))
- X buffer[i] = tolower(string[i]);
- X else
- X buffer[i] = string[i];
- X
- X buffer[strlen(string)] = 0;
- X
- X return( (char *) buffer);
- X}
- X
- XCenterline(line, string)
- Xint line;
- Xchar *string;
- X{
- X /** Output 'string' on the given line, centered. **/
- X
- X register int length, col;
- X
- X length = strlen(string);
- X
- X if (length > COLUMNS)
- X col = 0;
- X else
- X col = (COLUMNS - length) / 2;
- X
- X PutLine0(line, col, string);
- X}
- X
- Xchar *argv_zero(string)
- Xchar *string;
- X{
- X /** given a string of the form "/something/name" return a
- X string of the form "name"... **/
- X
- X static char buffer[NLEN];
- X register int i, j=0;
- X
- X for (i=strlen(string)-1; string[i] != '/'; i--)
- X buffer[j++] = string[i];
- X buffer[j] = '\0';
- X
- X reverse(buffer);
- X
- X return( (char *) buffer);
- X}
- X
- X#define MAX_RECURSION 20 /* up to 20 deep recursion */
- X
- Xchar *get_token(source, keys, depth)
- Xchar *source, *keys;
- Xint depth;
- X{
- X /** This function is similar to strtok() (see "opt_utils")
- X but allows nesting of calls via pointers...
- X **/
- X
- X register int last_ch;
- X static char *buffers[MAX_RECURSION];
- X char *return_value, *sourceptr;
- X
- X if (depth > MAX_RECURSION) {
- X error1("Get_token calls nested greater than %d deep!",
- X MAX_RECURSION);
- X emergency_exit();
- X }
- X
- X if (source != NULL)
- X buffers[depth] = source;
- X
- X sourceptr = buffers[depth];
- X
- X if (*sourceptr == '\0')
- X return(NULL); /* we hit end-of-string last time!? */
- X
- X sourceptr += strspn(sourceptr, keys); /* skip the bad.. */
- X
- X if (*sourceptr == '\0') {
- X buffers[depth] = sourceptr;
- X return(NULL); /* we've hit end-of-string */
- X }
- X
- X last_ch = strcspn(sourceptr, keys); /* end of good stuff */
- X
- X return_value = sourceptr; /* and get the ret */
- X
- X sourceptr += last_ch; /* ...value */
- X
- X if (*sourceptr != '\0') /** don't forget if we're at end! **/
- X sourceptr++;
- X
- X return_value[last_ch] = '\0'; /* ..ending right */
- X
- X buffers[depth] = sourceptr; /* save this, mate! */
- X
- X return((char *) return_value); /* and we're outta here! */
- X}
- SHAR_EOF
- chmod 0444 src/strings.c || echo "restore of src/strings.c fails"
- echo "x - extracting src/syscall.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/syscall.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: syscall.c,v 2.14 89/03/25 21:47:31 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.14 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: syscall.c,v $
- X * Revision 2.14 89/03/25 21:47:31 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** These routines are used for user-level system calls, including the
- X '!' command and the '|' commands...
- X
- X**/
- X
- X#include "headers.h"
- X
- X#include <signal.h>
- X
- X#ifdef BSD
- X# include <sys/wait.h>
- X#endif
- X
- Xchar *argv_zero();
- Xvoid _exit();
- X
- Xint
- Xsubshell()
- X{
- X /** spawn a subshell with either the specified command
- X returns non-zero if screen rewrite needed
- X **/
- X
- X char command[SLEN];
- X int ret;
- X int old_raw;
- X
- X PutLine0(LINES-3,COLUMNS-40,"(Use the shell name for a shell.)");
- X PutLine0(LINES-2,0,"Shell command: ");
- X command[0] = '\0';
- X (void) optionally_enter(command, LINES-2, 15, FALSE, FALSE);
- X if (strlen(command) == 0) {
- X MoveCursor(LINES-2,0); CleartoEOLN();
- X return(0);
- X }
- X
- X MoveCursor(LINES,0); CleartoEOLN();
- X if (( old_raw = RawState()) == ON)
- X Raw(OFF);
- X if (cursor_control) transmit_functions(OFF);
- X
- X ret = system_call(command, USER_SHELL, TRUE);
- X
- X PutLine0(LINES, 0, "\n\nPress any key to return to ELM.");
- X
- X if (old_raw == ON)
- X Raw(ON);
- X (void) getchar();
- X if (cursor_control) transmit_functions(ON);
- X
- X if (ret != 0) error1("Return code was %d.", ret);
- X return(1);
- X}
- X
- Xsystem_call(string, shell_type, allow_signals)
- Xchar *string;
- Xint shell_type, allow_signals;
- X{
- X /** execute 'string', setting uid to userid... **/
- X /** if shell-type is "SH" /bin/sh is used regardless of the
- X users shell setting. Otherwise, "USER_SHELL" is sent.
- X If allow_signals is TRUE, then allow the executed
- X command handle interrupt and hangup in its
- X own way. This is useful for executed programs with
- X user interaction that handle those signals on their
- X own terms. It is especially important for vi, so that
- X a message being edited when a user connection is
- X dropped is recovered by vi's expreserve program **/
- X
- X int stat = 0, pid, w;
- X#ifdef BSD
- X union wait status;
- X#else
- X int status;
- X#endif
- X#ifdef VOIDSIG
- X register void (*istat)(), (*qstat)();
- X# ifdef SIGTSTP
- X# ifndef BSD
- X register void (*oldstop)(), (*oldstart)();
- X# endif
- X# endif
- X#else
- X register int (*istat)(), (*qstat)();
- X# ifdef SIGTSTP
- X# ifndef BSD
- X register int (*oldstop)(), (*oldstart)();
- X# endif
- X# endif
- X#endif
- X
- X dprint(2, (debugfile,
- X "System Call: %s\n\t%s\n", shell_type == SH? "/bin/sh" : shell,
- X string));
- X
- X if ((pid = vfork()) == 0) {
- X setgid(groupid); /* and group id */
- X setuid(userid); /* back to the normal user! */
- X
- X if(allow_signals) {
- X /* program to exec should handle interrupt, accidental hangup, and stop signals */
- X (void)signal(SIGHUP, SIG_DFL);
- X (void)signal(SIGINT, SIG_DFL);
- X#ifdef SIGTSTP
- X# ifndef BSD
- X (void)signal(SIGTSTP, SIG_DFL);
- X (void)signal(SIGCONT, SIG_DFL);
- X# endif
- X#endif
- X } else {
- X /* program to exec should ignore interrupt, accidental hangup, and stop signals */
- X (void)signal(SIGHUP, SIG_IGN);
- X (void)signal(SIGINT, SIG_IGN);
- X#ifdef SIGTSTP
- X# ifndef BSD
- X (void)signal(SIGTSTP, SIG_IGN);
- X (void)signal(SIGCONT, SIG_IGN);
- X# endif
- X#endif
- X }
- X
- X if (strlen(shell) > 0 && shell_type == USER_SHELL) {
- X execl(shell, argv_zero(shell), "-c", string, (char *) 0);
- X }
- X else
- X execl("/bin/sh", "sh", "-c", string, (char *) 0);
- X _exit(127);
- X }
- X
- X istat = signal(SIGINT, SIG_IGN);
- X qstat = signal(SIGQUIT, SIG_IGN);
- X#ifdef SIGTSTP
- X# ifndef BSD
- X oldstop = signal(SIGTSTP, SIG_IGN);
- X oldstart = signal(SIGCONT, SIG_IGN);
- X# endif
- X#endif
- X
- X while ((w = wait(&status)) != pid && w != -1)
- X ;
- X
- X#ifdef BSD
- X if (status.w_retcode != 0) stat = status.w_retcode;
- X#else
- X if (w == -1) stat = status;
- X#endif
- X
- X (void)signal(SIGINT, istat);
- X (void)signal(SIGQUIT, qstat);
- X#ifdef SIGTSTP
- X# ifndef BSD
- X (void)signal(SIGTSTP, oldstop);
- X (void)signal(SIGCONT, oldstart);
- X# endif
- X#endif
- X
- X return(stat);
- X}
- X
- Xint
- Xdo_pipe()
- X{
- X /** pipe the current message or tagged messages to
- X the specified sequence.. **/
- X
- X char command[SLEN], buffer[SLEN], message_list[SLEN];
- X register int ret, to_pipe = 0, i;
- X int old_raw;
- X
- X message_list[0] = '\0'; /* NULL string to start... */
- X
- X for (i=0; i < message_count; i++)
- X if (ison(headers[i]->status, TAGGED)) {
- X sprintf(message_list,"%s %d", message_list,
- X headers[i]->index_number);
- X to_pipe++;
- X }
- X
- X if (!to_pipe) {
- X sprintf(message_list,"%d", headers[current-1]->index_number);
- X to_pipe = 1;
- X }
- X sprintf(buffer, "Pipe message%s to: ", plural(to_pipe));
- X PutLine0(LINES-2,0,buffer);
- X
- X command[0] = '\0';
- X
- X (void) optionally_enter(command, LINES-2, strlen(buffer), FALSE, FALSE);
- X if (strlen(command) == 0) {
- X MoveCursor(LINES-2,0); CleartoEOLN();
- X return(0);
- X }
- X
- X MoveCursor(LINES,0); CleartoEOLN();
- X if (( old_raw = RawState()) == ON)
- X Raw(OFF);
- X
- X if (cursor_control) transmit_functions(OFF);
- X
- X sprintf(buffer, "%s -f %s -h %s | %s",
- X readmsg,
- X (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
- X message_list,
- X command);
- X
- X ret = system_call(buffer, USER_SHELL, TRUE);
- X
- X PutLine0(LINES, 0, "\n\nPress any key to return to ELM.");
- X if (old_raw == ON)
- X Raw(ON);
- X (void) getchar();
- X if (cursor_control) transmit_functions(ON);
- X
- X if (ret != 0) error1("Return code was %d.", ret);
- X return(1);
- X}
- X
- Xprint_msg()
- X{
- X /** Print current message or tagged messages using 'printout'
- X variable. Error message iff printout not defined! **/
- X
- X char buffer[SLEN], filename[SLEN], printbuffer[SLEN];
- X char message_list[SLEN];
- X register int retcode, to_print = 0, i;
- X
- X if (strlen(printout) == 0) {
- X error("Don't know how to print - option \"printmail\" undefined!");
- X return;
- X }
- X
- X message_list[0] = '\0'; /* reset to null... */
- X
- X for (i=0; i < message_count; i++)
- X if (headers[i]->status & TAGGED) {
- X sprintf(message_list, "%s %d", message_list,
- X headers[i]->index_number);
- X to_print++;
- X }
- X
- X if (! to_print) {
- X sprintf(message_list," %d", headers[current-1]->index_number);
- X to_print = 1;
- X }
- X
- X sprintf(filename,"%s%d", temp_print, getpid());
- X
- X if (in_string(printout, "%s"))
- X sprintf(printbuffer, printout, filename);
- X else
- X sprintf(printbuffer, "%s %s", printout, filename);
- X
- X sprintf(buffer,"(%s -p -f %s%s > %s; %s 2>&1) > /dev/null",
- X readmsg,
- X (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
- X message_list,
- X filename,
- X printbuffer);
- X
- X dprint(2, (debugfile, "Printing system call...\n"));
- X
- X Centerline(LINES, "Queuing...");
- X
- X if ((retcode = system_call(buffer, SH, FALSE)) == 0) {
- X sprintf(buffer, "Message%s queued up to print.", plural(to_print));
- X Centerline(LINES, buffer);
- X }
- X else
- X error1("Printout failed with return code %d.", retcode);
- X
- X unlink(filename); /* remove da temp file! */
- X}
- X
- Xlist_folders(numlines, helpmsg)
- Xunsigned numlines;
- Xchar *helpmsg;
- X{
- X /** list the folders in the users FOLDERHOME directory. This is
- X simply a call to "ls -C"
- X Numlines is the number of lines to scroll afterwards. This is
- X useful when a portion of the screen needs to be cleared for
- X subsequent prompts, but you don't want to overwrite the
- X list of folders.
- X Helpmsg is what should be printed before the listing if not NULL.
- X **/
- X
- X char buffer[SLEN];
- X
- X Raw(OFF);
- X ClearScreen();
- X MoveCursor(LINES, 0);
- X if(helpmsg)
- X printf(helpmsg);
- X sprintf(buffer, "cd %s;ls -C", folders);
- X printf("\n\rContents of your folder directory:\n\r\n\r");
- X system_call(buffer, SH, FALSE);
- X while(numlines--)
- X printf("\n\r");
- X Raw(ON);
- X}
- SHAR_EOF
- chmod 0444 src/syscall.c || echo "restore of src/syscall.c fails"
- echo "x - extracting src/utils.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/utils.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: utils.c,v 2.22 89/03/25 21:47:33 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 2.22 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@dsinc.UUCP dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: utils.c,v $
- X * Revision 2.22 89/03/25 21:47:33 syd
- X * Initial 2.2 Release checkin
- X *
- X *
- X ******************************************************************************/
- X
- X/** Utility routines for ELM
- X
- X**/
- X
- X#include "headers.h"
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#ifdef BSD
- X#undef tolower
- X#endif
- X
- X#include <signal.h>
- X
- Xextern int errno;
- X
- Xchar *error_name();
- Xvoid exit();
- X
- Xcreate_new_folders()
- X{
- X /* this creates a new folders directory */
- X
- X char source[SLEN];
- X char com[SLEN];
- X
- X
- X /** Some systems don't have a mkdir call - how inconvienient! **/
- X
- X#ifdef MKDIR
- X (void) mkdir(folders, 0700);
- X#else
- X sprintf(com, "mkdir %s", folders);
- X system_call(com, SH, FALSE);
- X sprintf(com, "chmod 700 %s", folders);
- X system_call(com, SH, FALSE);
- X#endif /* MKDIR */
- X
- X chown( source, userid, groupid);
- X}
- X
- Xcreate_new_elmdir()
- X{
- X /** this routine is just for allowing new users who don't have the
- X old elm files to create a new .elm directory **/
- X
- X char source[SLEN];
- X char com[SLEN];
- X
- X
- X /** Some systems don't have a mkdir call - how inconvienient! **/
- X
- X#ifdef MKDIR
- X sprintf(source, "%s/.elm", home);
- X (void) mkdir(source, 0700);
- X#else
- X sprintf(com, "mkdir %s/.elm", home);
- X system_call(com, SH, FALSE);
- X sprintf(com, "chmod 700 %s/.elm", home);
- X system_call(com, SH, FALSE);
- X#endif /* MKDIR */
- X
- X chown( source, userid, groupid);
- X}
- X
- Xmove_old_files_to_new()
- X{
- X /** this routine is just for allowing people to transition from
- X the old Elm, where things are all kept in their $HOME dir,
- X to the new one where everything is in $HOME/.elm... **/
- X
- X char source[SLEN], dest[SLEN], temp[SLEN];
- X char com[SLEN];
- X
- X /** simply go through all the files... **/
- X
- X sprintf(source, "%s/.alias_text", home);
- X if (access(source, ACCESS_EXISTS) != -1) {
- X sprintf(dest, "%s/%s", home, ALIAS_TEXT);
- X printf("\n\rCopying from: %s\n\rCopying to: %s\n\r", source, dest);
- X
- X sprintf(temp, "/tmp/%d", getpid());
- X sprintf(com, "%s -e 's/:/=/g' %s > %s\n", sed_cmd, source, temp);
- X (void) system_call(com, SH, FALSE);
- X sprintf(com, "%s %s %s\n", move_cmd, temp, dest);
- X (void) system_call(com, SH, FALSE);
- X (void) system_call("newalias", SH, FALSE);
- X }
- X
- X sprintf(source, "%s/.elmheaders", home);
- X if (access(source, ACCESS_EXISTS) != -1) {
- X sprintf(dest, "%s/%s", home, mailheaders);
- X printf("\n\rCopying from: %s\n\rCopying to: %s\n\r", source, dest);
- X copy(source, dest);
- X }
- X
- X sprintf(source, "%s/.elmrc", home);
- X if (access(source, ACCESS_EXISTS) != -1) {
- X sprintf(dest, "%s/%s", home, elmrcfile);
- X printf("\n\rCopying from: %s\n\rCopying to: %s\n\r", source, dest);
- X copy(source, dest);
- X }
- X
- X printf(
- X "\n\rWelcome to the new version of ELM!\n\n\rHit return to continue.");
- X getchar();
- X}
- X
- Xshow_mailfile_stats()
- X{
- X /** when we're about to die, let's try to dump lots of good stuff
- X to the debug file... **/
- X
- X struct stat buffer;
- X
- X if (debug == 0) return; /* Damn! Can't do it! */
- X
- X if (fstat(fileno(mailfile), &buffer) == 0) {
- SHAR_EOF
- echo "End of part 21"
- echo "File src/utils.c is continued in part 22"
- echo "22" > s2_seq_.tmp
- exit 0
-
-