home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i081: ELM mail syste, release 2.3, Part22/26
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 0e2b97fa ddaa5585 f39798e4 27be6325
-
- Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
- Posting-number: Volume 22, Issue 81
- Archive-name: elm2.3/part22
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # this is part 22 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file src/showmsg.c continued
- #
- CurArch=22
- 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"
- sed 's/^X//' << 'SHAR_EOF' >> src/showmsg.c
- X sleep(2);
- X break;
- X }
- X if ((buf_len=strlen(buffer)) > 0) {
- X if(buffer[buf_len - 1] == '\n') {
- X lines--;
- X lines_displayed++;
- X }
- X no_ret(buffer);
- X }
- X
- X if (strlen(buffer) == 0) {
- X weed_header = 0; /* past header! */
- X weeding_out = 0;
- X }
- X
- X if (form_letter && weed_header)
- X /* skip it. NEVER display random headers in forms! */;
- X else if (weed_header && matches_weedlist(buffer))
- X weeding_out = 1; /* aha! We don't want to see this! */
- X else if (buffer[0] == '[') {
- X if (strcmp(buffer, START_ENCODE)==0)
- X crypted = ON;
- X else if (strcmp(buffer, END_ENCODE)==0)
- X crypted = OFF;
- X else if (crypted) {
- X encode(buffer);
- X val = show_line(buffer, builtin);
- X }
- X else
- X val = show_line(buffer, builtin);
- X }
- X else if (crypted) {
- X encode(buffer);
- X val = show_line(buffer, builtin);
- X }
- X else if (weeding_out) {
- X weeding_out = (whitespace(buffer[0])); /* 'n' line weed */
- X if (! weeding_out) /* just turned on! */
- X val = show_line(buffer, builtin);
- X }
- X else if (form_letter && first_word(buffer,"***") && filter) {
- X strcpy(buffer,
- X"\n------------------------------------------------------------------------------\n");
- X val = show_line(buffer, builtin); /* hide '***' */
- X form_letter_section++;
- X }
- X else if (form_letter_section == 1 || form_letter_section == 3)
- X /** skip this stuff - we can't deal with it... **/;
- X else
- X val = show_line(buffer, builtin);
- X
- X if (val != 0) /* discontinue the display */
- X break;
- X }
- X
- X if (cursor_control) transmit_functions(ON);
- X
- X if (!builtin) {
- X fclose(pipe_wr_fp);
- X while ((wait_ret = wait(&wait_stat)) != fork_ret
- X && wait_ret!= -1)
- X ;
- X /* turn raw on **after** child terminates in case child
- X * doesn't put us back to cooked mode after we return ourselves
- X * to raw.
- X */
- X Raw(ON);
- X }
- X
- X /* If we are to prompt for a user input command and we don't
- X * already have one */
- X if ((prompt_after_pager || builtin) && val == 0) {
- X MoveCursor(LINES,0);
- X StartBold();
- X Write_to_screen(" Command ('i' to return to index): ", 0);
- X EndBold();
- X fflush(stdout);
- X val = ReadCh();
- X }
- X
- X if (memory_lock) EndMemlock(); /* turn it off!! */
- X
- X /* 'q' means quit current operation and pop back up to previous level -
- X * in this case it therefore means return to index screen.
- X */
- X return(val == 'i' || val == 'q' ? 0 : val);
- X}
- X
- Xint
- Xshow_line(buffer, builtin)
- Xchar *buffer;
- Xint builtin;
- X{
- X /** Hands the given line to the output pipe. 'builtin' is true if
- X we're using the builtin pager.
- X Return the character entered by the user to indicate
- X a command other than continuing with the display (only possible
- X with the builtin pager), otherwise 0. **/
- X
- X#ifdef MMDF
- X if (strcmp(buffer, MSG_SEPERATOR) == 0)
- X strcpy(buffer," ");
- X#endif /* MMDF */
- X if (builtin) {
- X strcat(buffer, "\n");
- X return(display_line(buffer));
- X }
- X errno = 0;
- X fprintf(pipe_wr_fp, "%s\n", buffer);
- X if (errno != 0)
- X dprint(1, (debugfile, "\terror %s hit!\n", error_name(errno)));
- X return(0);
- X}
- SHAR_EOF
- echo "File src/showmsg.c is complete"
- chmod 0444 src/showmsg.c || echo "restore of src/showmsg.c fails"
- echo "x - extracting src/showmsg_c.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/showmsg_c.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: showmsg_c.c,v 4.1 90/04/28 22:44:08 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: showmsg_c.c,v $
- X * Revision 4.1 90/04/28 22:44:08 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This is an interface for the showmsg command line. The possible
- X functions that could be invoked from the showmsg command line are
- X almost as numerous as those from the main command line and include
- X the following;
- X
- X | = pipe this message to command...
- X ! = call Unix command
- X < = scan message for calendar info
- X b = bounce (remail) message
- X d = mark message for deletion
- X f = forward message
- X g = group reply
- X h = redisplay this message from line #1, showing headers
- X <CR> = redisplay this message from line #1, weeding out headers
- X i,q = move back to the index page (simply returns from function)
- X J = move to body of next message
- X j,n = move to body of next undeleted message
- X K = move to body of previous message
- X k = move to body of previous undeleted message
- X m = mail a message out to someone
- X p = print this (all tagged) message
- X r = reply to this message
- X s = save this message to a maibox/folder
- X t = tag this message
- X u = undelete message
- X x = Exit Elm NOW
- X
- X all commands not explicitly listed here are beeped at. Use i)ndex
- X to get back to the main index page, please.
- X
- X This function returns when it is ready to go back to the index
- X page.
- X**/
- X
- X#include "headers.h"
- X
- Xint screen_mangled = 0;
- Xchar msg_line[SLEN];
- X#define store_msg(a) (void)strcpy(msg_line,a)
- X#define put_prompt() PutLine0(LINES-3, 0, "Command:")
- X#define put_help() PutLine0(LINES-3, 45, "(Use 'i' to return to index.)")
- X#define POST_PROMPT_COL strlen("Command: ")
- X
- X
- Xint
- Xprocess_showmsg_cmd(command)
- Xint command;
- X{
- X int i, intbuf; /* for dummy parameters...etc */
- X int ch; /* for arrow keys */
- X int key_offset; /* for arrow keys */
- X int istagged; /* for tagging and subsequent msg */
- X
- X Raw(ON);
- X
- X while (TRUE) {
- X clear_error();
- X switch (command) {
- X case '?' : if (help(TRUE)) {
- X ClearScreen();
- X build_bottom();
- X } else screen_mangled = TRUE;
- X break;
- X
- X case '|' : put_cmd_name("Pipe", TRUE);
- X (void) do_pipe(); /* do pipe - ignore return val */
- X ClearScreen();
- X build_bottom();
- X break;
- X
- X#ifdef ALLOW_SUBSHELL
- X case '!' : put_cmd_name("System call", TRUE);
- X (void) subshell();
- X ClearScreen();
- X build_bottom();
- X break;
- X#endif
- X
- X case '<' :
- X#ifdef ENABLE_CALENDAR
- X put_cmd_name("Scan messages for calendar entries", TRUE);
- X scan_calendar();
- 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' : put_cmd_name("Exit", TRUE);
- X exit_prog();
- X break;
- 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 = ReadCh(); /* 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
- 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 4.1 90/04/28 22:44:10 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: signals.c,v $
- X * Revision 4.1 90/04/28 22:44:10 syd
- X * checkin of Elm 2.3 as of Release PL0
- 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
- X#ifdef VOIDSIG
- Xtypedef void sighan_type;
- X#else
- Xtypedef int sighan_type;
- X#endif
- X
- Xextern int pipe_abort; /* set to TRUE if receive SIGPIPE */
- X
- Xsighan_type
- Xquit_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGQUIT **\n\n\n\n"));
- X leave();
- X}
- X
- Xsighan_type
- Xhup_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGHUP **\n\n\n\n"));
- X leave();
- X}
- X
- Xsighan_type
- Xterm_signal()
- X{
- X dprint(1, (debugfile, "\n\n** Received SIGTERM **\n\n\n\n"));
- X leave();
- X}
- X
- Xsighan_type
- 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
- Xsighan_type
- 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
- Xsighan_type
- 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
- Xsighan_type
- 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
- Xsighan_type
- Xalarm_signal()
- X{
- X /** silently process alarm signal for timeouts... **/
- X#ifdef BSD
- X if (InGetPrompt)
- X longjmp(GetPromptBuf, 1);
- X#else
- X signal(SIGALRM, alarm_signal);
- X#endif
- X}
- X
- Xsighan_type
- Xpipe_signal()
- X{
- X /** silently process pipe signal... **/
- 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
- Xsighan_type
- Xsig_user_stop()
- 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
- Xsighan_type
- Xsig_return_from_user_stop()
- X{
- X /** this is called when returning from a ^Z stop **/
- 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#ifdef BSD
- X if (InGetPrompt)
- X longjmp(GetPromptBuf, 1);
- X#endif
- 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 4.1 90/04/28 22:44:11 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: softkeys.c,v $
- X * Revision 4.1 90/04/28 22:44:11 syd
- X * checkin of Elm 2.3 as of Release PL0
- 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 4.1 90/04/28 22:44:12 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: sort.c,v $
- X * Revision 4.1 90/04/28 22:44:12 syd
- X * checkin of Elm 2.3 as of Release PL0
- 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 if (entries > 1)
- 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 long diff;
- X
- X first = *p1;
- X second = *p2;
- X
- X switch (abs(sortby)) {
- X case SENT_DATE:
- X diff = first->time_sent - second->time_sent;
- X if ( diff < 0 ) ret = -1;
- X else if ( diff > 0 ) ret = 1;
- X else ret = 0;
- 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 4.1 90/04/28 22:44:14 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: string2.c,v $
- X * Revision 4.1 90/04/28 22:44:14 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains string functions that are shared throughout the
- X various ELM utilities...
- X
- X**/
- X
- X#include "headers.h"
- X#include <ctype.h>
- X
- X#ifdef BSD
- X#undef tolower
- X#undef toupper
- X#endif
- 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[VERY_LONG_STRING];
- X register char *bufptr = buffer;
- X
- X for (; *string; string++, bufptr++)
- X if (isupper(*string))
- X *bufptr = tolower(*string);
- X else
- X *bufptr = *string;
- X
- X *bufptr = 0;
- X
- X return( (char *) buffer);
- X}
- X
- X
- Xint
- Xin_list(list, target)
- Xchar *list, *target;
- X
- X{
- X /* Returns TRUE iff target is an item in the list - case ignored.
- X * If target is simple (an atom of an address) match must be exact.
- X * If target is complex (contains a special character that separates
- X * address atoms), the target need only match a whole number of atoms
- X * at the right end of an item in the list. E.g.
- X * target: item: match:
- X * joe joe yes
- X * joe jojoe no (wrong logname)
- X * joe machine!joe no (similar logname on a perhaps
- X * different machine - to
- X * test this sort of item the
- X * passed target must include
- X * proper machine name, is
- X * in next two examples)
- X * machine!joe diffmachine!joe no "
- X * machine!joe diffmachine!machine!joe yes
- X * joe@machine jojoe@machine no (wrong logname)
- X * joe@machine diffmachine!joe@machine yes
- X */
- X
- X register char *rest_of_list,
- X *next_item,
- X ch;
- X int offset;
- X char *shift_lower(),
- X lower_list[VERY_LONG_STRING],
- X lower_target[SLEN];
- X
- X rest_of_list = strcpy(lower_list, shift_lower(list));
- X strcpy(lower_target, shift_lower(target));
- X while((next_item = strtok(rest_of_list, ", \t\n")) != NULL) {
- X /* see if target matches the whole item */
- X if(strcmp(next_item, lower_target) == 0)
- X return(TRUE);
- X
- X if(strpbrk(lower_target,"!@%:") != NULL) {
- X
- X /* Target is complex */
- X
- X if((offset = strlen(next_item) - strlen(lower_target)) > 0) {
- X
- X /* compare target against right end of next item */
- X if(strcmp(&next_item[offset], lower_target) == 0) {
- X
- X /* make sure we are comparing whole atoms */
- X ch=next_item[offset-1];
- X if(ch == '!' || ch == '@' || ch == '%' || ch == ':')
- X return(TRUE);
- X }
- X }
- X }
- X rest_of_list = NULL;
- X }
- X return(FALSE);
- X}
- X
- 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, len;
- X
- X for (i=0, len = strlen(string); i<len; 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;
- X
- X for (; *string; string++)
- X if (*string == 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); --i >= 0 && whitespace(string[i]); )
- X /** spin backwards, semicolon intented **/ ;
- 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 4.1 90/04/28 22:44:16 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: strings.c,v $
- X * Revision 4.1 90/04/28 22:44:16 syd
- X * checkin of Elm 2.3 as of Release PL0
- 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(),
- X *get_token(), *strip_parens(), *argv_zero(), *strcpy(), *strncpy();
- X
- Xchar *index();
- 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
- X/**
- X This routine will return true if the "addr" contains the "user" subject
- X to the following contstraints: (1) either the "user" is at the front
- X of "addr" or it is preceded by an appropriate meta-char, and (2)
- X either the "user" is at the end of "addr" or it is suceeded by an
- X appropriate meta-char.
- X**/
- Xint addr_matches_user(addr,user)
- Xregister char *addr, *user;
- X{
- X int len = strlen(user);
- X static char c_before[] = "!:%"; /* these can appear before a username */
- X static char c_after[] = ":%@"; /* these can appear after a username */
- X
- X do {
- X if ( strncmp(addr,user,len) == 0 ) {
- X if ( addr[len] == '\0' || index(c_after,addr[len]) != NULL )
- X return TRUE;
- X }
- X } while ( (addr=strpbrk(addr,c_before)) != NULL && *++addr != '\0' ) ;
- X return FALSE;
- 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", hostfullname);
- X if (chloc(from,'!') != -1 && in_string(from, buffer))
- X from[strlen(from)-strlen(buffer)] = '\0';
- X
- X#endif
- X
- X /**
- X Produce a simplified version of the from into buffer. If the
- X from is just "username" or "Full Username" it will be preserved.
- X If it is an address, the rightmost "stuff!stuff", "stuff@stuff",
- X or "stuff:stuff" will be used.
- 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 buffer[i] = '\0';
- X reverse(buffer);
- X
- X#ifdef MMDF
- X if (strlen(buffer) == 0) {
- 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#endif /* MMDF */
- X
- X if ( strcmp(buffer,full_username) == 0 ||
- X addr_matches_user(buffer,username) ) {
- 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, len;
- 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), len = strlen(word); i<len; i++)
- X ret_buffer[iindex++] = word[i];
- X current_length = len + 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), len = strlen(word); i<len; i++)
- X ret_buffer[iindex++] = word[i];
- X current_length += len;
- 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 char *strptr = string;
- X
- X for (; *strptr; strptr++)
- X if (*strptr == COMMA)
- X *strptr = 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 depth = 0, buffer_index = 0;
- X
- X for (; *string; string++) {
- X if (*string == '(')
- X depth++;
- X else if (*string == ')')
- X depth--;
- X else if (depth == 0)
- X buffer[buffer_index++] = *string;
- 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 /** skip leading white space, just in case.. **/
- X
- X while(whitespace(*buffer)) buffer++;
- X
- X /** now copy into 'first' until we hit white space or EOLN **/
- X
- X for (; *buffer && ! whitespace(*buffer); buffer++, first++)
- X if (islower(*buffer))
- X *first = tolower(*buffer);
- X else
- X *first = *buffer;
- X
- X *first = '\0';
- X
- X while (whitespace(*buffer)) buffer++;
- X
- X for (; *buffer; buffer++, rest++)
- X if (islower(*buffer))
- X *rest = tolower(*buffer);
- X else
- X *rest = *buffer;
- X
- X *rest = '\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, len;
- X
- X for (iindex=0, len = strlen(string);! whitespace(string[iindex]) && iindex < len;
- 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
- 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}
- X
- X
- Xquote_args(out_string,in_string)
- Xregister char *out_string, *in_string;
- X{
- X /** Copy from "in_string" to "out_string", collapsing multiple
- X white space and quoting each word. Returns a pointer to
- X the resulting word.
- X **/
- X
- X int empty_string = TRUE;
- X
- X while ( *in_string != '\0' ) {
- X
- X /** If this is a space then advance to the start of the next word.
- X Otherwise, copy through the word surrounded by quotes.
- X **/
- X
- X if ( isspace(*in_string) ) {
- X while ( isspace(*in_string) )
- X ++in_string;
- X } else {
- X *out_string++ = '"';
- X while ( *in_string != '\0' && !isspace(*in_string) )
- X *out_string++ = *in_string++;
- X *out_string++ = '"';
- X *out_string++ = ' ';
- X empty_string = FALSE;
- X }
- X
- X }
- X
- X if ( !empty_string )
- X --out_string;
- X *out_string = '\0';
- X}
- 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 4.1 90/04/28 22:44:18 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: syscall.c,v $
- X * Revision 4.1 90/04/28 22:44:18 syd
- X * checkin of Elm 2.3 as of Release PL0
- 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
- X#ifdef ALLOW_SUBSHELL
- 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];
- SHAR_EOF
- echo "End of part 22"
- echo "File src/syscall.c is continued in part 23"
- echo "23" > s2_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-