home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i080: ELM mail syste, release 2.3, Part21/26
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: f1fdbb4c c5394e13 05a19944 5c9ca15e
-
- Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
- Posting-number: Volume 22, Issue 80
- Archive-name: elm2.3/part21
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # this is part 21 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file src/returnadd.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/returnadd.c"
- sed 's/^X//' << 'SHAR_EOF' >> src/returnadd.c
- X
- X buffer[0] = '\0';
- X
- X ok = (int) (fgets(buf2, SLEN, mailfile) != NULL);
- X if (ok)
- X if(buf2[strlen(buf2)-1] == '\n') lines--; /* got a full line */
- X
- X while (ok && lines) {
- X buf[0] = '\0';
- X strncat(buf, buf2, SLEN);
- X ok = (int) (fgets(buf2, SLEN, mailfile) != NULL);
- X if (ok)
- X if(buf2[strlen(buf2)-1] == '\n') lines--; /* got a full line */
- X while (ok && lines && whitespace(buf2[0])) {
- X if (buf[strlen(buf)-1] == '\n')
- X buf[strlen(buf)-1] = '\0';
- X strncat(buf, buf2, (SLEN-strlen(buf)-1));
- X ok = (int) (fgets(buf2, SLEN, mailfile) != NULL);
- X if (ok)
- X if(buf2[strlen(buf2)-1] == '\n') lines--; /* got a full line */
- X }
- X
- X/* At this point, "buf" contains the unfolded header line, while "buf2" contains
- X the next single line of text from the mail file */
- X
- X if (first_word(buf, "From "))
- X sscanf(buf, "%*s %s", hold_return);
- X else if (first_word(buf, ">From")) {
- X sscanf(buf,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s %s",
- X name1, name2, alt_name2);
- X if (strcmp(name2, "from") == 0) /* remote from xyz */
- X strcpy(name2, alt_name2);
- X else if (strcmp(name2, "by") == 0) /* forwarded by xyz */
- X strcpy(name2, alt_name2);
- X add_site(buffer, name2, lastname);
- X }
- X
- X#ifdef USE_EMBEDDED_ADDRESSES
- X
- X else if (first_word(buf, "From:")) {
- X get_address_from("From:", buf, hold_return);
- X buffer[0] = '\0';
- X }
- X else if (first_word(buf, "Reply-To:")) {
- X get_address_from("Reply-To:", buf, buffer);
- X return(using_to);
- X }
- X
- X#endif
- X
- X else if (strlen(buf) < 2) /* done with header */
- X lines = 0; /* let's get outta here! We're done!!! */
- X }
- X
- X if (buffer[0] == '\0')
- X strcpy(buffer, hold_return); /* default address! */
- X else
- X add_site(buffer, name1, lastname); /* get the user name too! */
- X
- X if (first_word(buffer, "To:")) { /* for backward compatibility */
- X get_existing_address(buffer,msgnum);
- X using_to = TRUE;
- X }
- X else {
- X /*
- X * KLUDGE ALERT - DANGER WILL ROBINSON
- X * We can't just leave a bare login name as the return address,
- X * or it will be alias-expanded.
- X * So we qualify it with the current host name (and, maybe, domain).
- X * Sigh.
- X */
- X
- X if (chloc(buffer, '@') < 0
- X && chloc(buffer, '%') < 0
- X && chloc(buffer, '!') < 0)
- X {
- X#ifdef INTERNET
- X sprintf(buffer + strlen(buffer), "@%s", hostfullname);
- X#else
- X strcpy(buf, buffer);
- X sprintf(buffer, "%s!%s", hostname, buf);
- X#endif
- X }
- X
- X /*
- X * If we have a space character,
- X * or we DON'T have '!' or '@' chars,
- X * append the user-readable name.
- X */
- X if (chloc(headers[msgnum]->from, ' ') >= 0 ||
- X (chloc(headers[msgnum]->from, '!') < 0 &&
- X chloc(headers[msgnum]->from, '@') < 0)) {
- X sprintf(buffer + strlen(buffer),
- X " (%s)", headers[msgnum]->from);
- X }
- X }
- X
- X return(using_to);
- X}
- X
- Xget_existing_address(buffer, msgnum)
- Xchar *buffer;
- Xint msgnum;
- X{
- X /** This routine is called when the message being responded to has
- X "To:xyz" as the return address, signifying that this message is
- X an automatically saved copy of a message previously sent. The
- X correct to address can be obtained fairly simply by reading the
- X To: header from the message itself and (blindly) copying it to
- X the given buffer. Note that this header can be either a normal
- X "To:" line (Elm) or "Originally-To:" (previous versions e.g.Msg)
- X **/
- X
- X char mybuf[LONG_STRING];
- X register char ok = 1, in_to = 0;
- X
- X buffer[0] = '\0';
- X
- X /** first off, let's get to the beginning of the message... **/
- X
- X if(msgnum < 0 || msgnum >= message_count || message_count < 1) {
- X dprint(1, (debugfile,
- X "Error: %d not a valid message number message_count = %d (%s)",
- X msgnum, message_count, "get_existing_address"));
- X error1("%d not a valid message number!");
- X return;
- X }
- X if (fseek(mailfile, headers[msgnum]->offset, 0) == -1) {
- X dprint(1, (debugfile,
- X "Error: seek %ld bytes into file hit errno %s (%s)",
- X headers[msgnum]->offset, error_name(errno),
- X "get_existing_address"));
- X error2("Couldn't seek %d bytes into the file (%s).",
- X headers[msgnum]->offset, error_name(errno));
- X return;
- X }
- X
- X /** okay! Now we're there! **/
- X
- X while (ok) {
- X ok = (int) (fgets(mybuf, LONG_STRING, mailfile) != NULL);
- X no_ret(mybuf); /* remove return character */
- X
- X if (first_word(mybuf, "To: ")) {
- X in_to = TRUE;
- X strcpy(buffer, (char *) mybuf + strlen("To: "));
- X }
- X else if (first_word(mybuf, "Original-To:")) {
- X in_to = TRUE;
- X strcpy(buffer, (char *) mybuf + strlen("Original-To:"));
- X }
- X else if (in_to && whitespace(mybuf[0])) {
- X strcat(buffer, " "); /* tag a space in */
- X strcat(buffer, (char *) mybuf + 1); /* skip 1 whitespace */
- X }
- X else if (strlen(mybuf) < 2)
- X return; /* we're done for! */
- X else
- X in_to = 0;
- X }
- X}
- SHAR_EOF
- echo "File src/returnadd.c is complete"
- chmod 0444 src/returnadd.c || echo "restore of src/returnadd.c fails"
- echo "x - extracting src/save_opts.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/save_opts.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: save_opts.c,v 4.1 90/04/28 22:44:00 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: save_opts.c,v $
- X * Revision 4.1 90/04/28 22:44:00 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains the routine needed to allow the users to change the
- X Elm parameters and then save the configuration in a ".elm/elmrc" file in
- X their home directory. With any luck this will allow them never to have
- X to actually EDIT the file!!
- X
- X**/
- X
- X#include "headers.h"
- X#include <errno.h>
- X
- X#undef onoff
- X#define onoff(n) (n == 1? "ON":"OFF")
- X
- X#define absolute(x) ((x) < 0? -(x) : (x))
- X
- Xextern int errno;
- Xextern char version_buff[];
- X
- Xchar *error_name(), *sort_name();
- Xlong ftell();
- X
- X#include "save_opts.h"
- X
- XFILE *elminfo; /* informational file as needed... */
- X
- Xsave_options()
- X{
- X /** Save the options currently specified to a file. This is a
- X fairly complex routine since it tries to put in meaningful
- X comments and such as it goes along. The comments are
- X extracted from the file ELMRC_INFO as defined in the sysdefs.h
- X file. THAT file has the format;
- X
- X varname
- X <comment>
- X <comment>
- X <blank line>
- X
- X and each comment is written ABOVE the variable to be added. This
- X program also tries to make 'pretty' stuff like the alternatives
- X and such.
- X **/
- X
- X FILE *newelmrc;
- X char oldfname[SLEN], newfname[SLEN];
- X
- X sprintf(newfname, "%s/%s", home, elmrcfile);
- X sprintf(oldfname, "%s/%s", home, old_elmrcfile);
- X
- X /** first off, let's see if they already HAVE a .elm/elmrc file **/
- X
- X save_file_stats(newfname);
- X if (access(newfname, ACCESS_EXISTS) != -1) {
- X /** YES! Copy it to the file ".old.elmrc".. **/
- X if (rename(newfname, oldfname) < 0)
- X dprint(2, (debugfile, "Unable to rename %s to %s\n",
- X newfname, oldfname));
- X (void) chown(oldfname, userid, groupid);
- X
- X }
- X
- X /** now let's open the datafile if we can... **/
- X
- X if ((elminfo = fopen(ELMRC_INFO, "r")) == NULL)
- X error1("Warning: saving without comments! Can't get to %s.",
- X ELMRC_INFO);
- X
- X /** next, open the new .elm/elmrc file... **/
- X
- X if ((newelmrc = fopen(newfname, "w")) == NULL) {
- X error2("Can't save configuration! Can't write to %s [%s].",
- X newfname, error_name(errno));
- X return;
- X }
- X
- X save_user_options(elminfo, newelmrc);
- X restore_file_stats(newfname);
- X
- X error1("Options saved in file %s.", newfname);
- X}
- X
- Xsave_user_options(elminfo_fd, newelmrc)
- XFILE *elminfo_fd, *newelmrc;
- X{
- X /** save the information in the file. If elminfo_fd == NULL don't look
- X for comments!
- X **/
- X
- X if (elminfo_fd != NULL)
- X build_offset_table(elminfo_fd);
- X
- X fprintf(newelmrc,
- X "#\n# .elm/elmrc - options file for the ELM mail system\n#\n");
- X
- X if (strlen(full_username) > 0)
- X fprintf(newelmrc, "# Saved automatically by ELM %s for %s\n#\n\n",
- X version_buff, full_username);
- X else
- X fprintf(newelmrc, "# Saved automatically by ELM %s\n#\n\n", version_buff);
- X fprintf(newelmrc,"# For yes/no settings with ?, ON means yes, OFF means no\n\n");
- X
- X save_option_string(CALENDAR, raw_calendar_file, newelmrc, FALSE);
- X save_option_string(EDITOR, raw_editor, newelmrc, FALSE);
- X
- X save_option_char(ESCAPECHAR, escape_char, newelmrc);
- X
- X save_option_string(FULLNAME, full_username, newelmrc, FALSE);
- X save_option_string(RECEIVEDMAIL, raw_recvdmail, newelmrc, FALSE);
- X save_option_string(MAILDIR, raw_folders, newelmrc, FALSE);
- X save_option_string(TMPDIR, temp_dir, newelmrc, FALSE);
- X save_option_string(PAGER, raw_pager, newelmrc, FALSE);
- X save_option_string(PREFIX, prefixchars, newelmrc, TRUE);
- X save_option_string(PRINT, raw_printout, newelmrc, FALSE);
- X save_option_string(SENTMAIL, raw_sentmail, newelmrc, FALSE);
- X save_option_string(SHELL, raw_shell, newelmrc, FALSE);
- X
- X save_option_string(LOCALSIGNATURE, raw_local_signature,
- X newelmrc, FALSE);
- X save_option_string(REMOTESIGNATURE, raw_remote_signature,
- X newelmrc, FALSE);
- X save_option_on_off(SIGDASHES, sig_dashes, newelmrc);
- X
- X save_option_sort(SORTBY, newelmrc);
- X
- X save_option_on_off(ALWAYSDELETE, always_del, newelmrc);
- X save_option_on_off(ALWAYSSTORE, always_store, newelmrc);
- X save_option_on_off(ALWAYSKEEP, always_keep, newelmrc);
- X save_option_on_off(ARROW, arrow_cursor, newelmrc);
- X save_option_on_off(ASK, question_me, newelmrc);
- X save_option_on_off(ASKCC, prompt_for_cc, newelmrc);
- X save_option_string(ATTRIBUTION, attribution, newelmrc, FALSE);
- X save_option_on_off(AUTOCOPY, auto_copy, newelmrc);
- X
- X save_option_number(BOUNCEBACK, bounceback, newelmrc);
- X
- X save_option_on_off(COPY, auto_cc, newelmrc);
- X save_option_on_off(FORCENAME, force_name, newelmrc);
- X save_option_on_off(FORMS, (allow_forms != NO), newelmrc);
- X save_option_on_off(KEEPEMPTY, keep_empty_files, newelmrc);
- X save_option_on_off(KEYPAD, hp_terminal, newelmrc);
- X save_option_on_off(MENU, mini_menu, newelmrc);
- X save_option_on_off(MOVEPAGE, move_when_paged, newelmrc);
- X save_option_on_off(NAMES, names_only, newelmrc);
- X save_option_on_off(NOHEADER, noheader, newelmrc);
- X save_option_on_off(POINTNEW, point_to_new, newelmrc);
- X save_option_on_off(PROMPTAFTER, prompt_after_pager, newelmrc);
- X save_option_on_off(RESOLVE, resolve_mode, newelmrc);
- X save_option_on_off(SAVENAME, save_by_name, newelmrc);
- X save_option_on_off(SOFTKEYS, hp_softkeys, newelmrc);
- X
- X save_option_number(TIMEOUT, (int) timeout, newelmrc);
- X
- X save_option_on_off(TITLES, title_messages, newelmrc);
- X
- X save_option_number(USERLEVEL, user_level, newelmrc);
- X
- X save_option_on_off(WARNINGS, warnings, newelmrc);
- X save_option_on_off(WEED, filter, newelmrc);
- X
- X save_option_weedlist(WEEDOUT, newelmrc);
- X save_option_alternatives(ALTERNATIVES, alternative_addresses, newelmrc);
- X
- X fclose(newelmrc);
- X if ( elminfo_fd != NULL ) {
- X fclose(elminfo_fd);
- X }
- X}
- X
- Xsave_option_string(iindex, value, fd, underscores)
- Xint iindex, underscores;
- Xchar *value;
- XFILE *fd;
- X{
- X /** Save a string option to the file... only subtlety is when we
- X save strings with spaces in 'em - translate to underscores!
- X **/
- X
- X char buffer[SLEN], *bufptr;
- X
- X add_comment(iindex, fd);
- X
- X strcpy(buffer, value);
- X
- X if (underscores)
- X for (bufptr = buffer; *bufptr; bufptr++)
- X if (*bufptr == SPACE) *bufptr = '_';
- X
- X fprintf(fd, "%s = %s\n\n", save_info[iindex].name, buffer);
- X}
- X
- Xsave_option_sort(iindex, fd)
- Xint iindex;
- XFILE *fd;
- X{
- X /** save the current sorting option to a file **/
- X
- X add_comment(iindex, fd);
- X
- X fprintf(fd, "%s = %s\n\n", save_info[iindex].name,
- X sort_name(SHORT));
- X}
- X
- Xsave_option_char(iindex, value, fd)
- Xint iindex;
- Xchar value;
- XFILE *fd;
- X{
- X /** Save a character option to the file **/
- X
- X add_comment(iindex, fd);
- X
- X fprintf(fd, "%s = %c\n\n", save_info[iindex].name, value);
- X}
- X
- Xsave_option_number(iindex, value, fd)
- Xint iindex, value;
- XFILE *fd;
- X{
- X /** Save a binary option to the file - boy is THIS easy!! **/
- X
- X add_comment(iindex, fd);
- X
- X fprintf(fd, "%s = %d\n\n", save_info[iindex].name, value);
- X}
- X
- Xsave_option_on_off(iindex, value, fd)
- Xint iindex, value;
- XFILE *fd;
- X{
- X /** Save a binary option to the file - boy is THIS easy!! **/
- X
- X add_comment(iindex, fd);
- X
- X fprintf(fd, "%s = %s\n\n", save_info[iindex].name, onoff(value));
- X}
- X
- Xsave_option_weedlist(iindex, fd)
- Xint iindex;
- XFILE *fd;
- X{
- X /** save a list of weedout headers to the file **/
- X
- X int length_so_far = 0, i;
- X
- X add_comment(iindex, fd);
- X
- X length_so_far = strlen(save_info[iindex].name) + 4;
- X
- X fprintf(fd, "%s = ", save_info[iindex].name);
- X
- X /** first off, skip till we get past the default list **/
- X
- X for (i = 0; i < weedcount; i++)
- X if (strcmp(weedlist[i],"*end-of-defaults*") == 0)
- X break;
- X
- X while (i < weedcount) {
- X if (strcmp(weedlist[i], "*end-of-defaults*") != 0)
- X break;
- X i++; /* and get PAST it too! */
- X }
- X
- X while (i < weedcount) {
- X if (strlen(weedlist[i]) + length_so_far > 78) {
- X fprintf(fd, "\n\t");
- X length_so_far = 8;
- X }
- X fprintf(fd, "\"%s\" ", weedlist[i]);
- X length_so_far += (strlen(weedlist[i]) + 4);
- X i++;
- X }
- X fprintf(fd, "\t\"*end-of-user-headers*\"\n\n");
- X}
- X
- Xsave_option_alternatives(iindex, list, fd)
- Xint iindex;
- Xstruct addr_rec *list;
- XFILE *fd;
- X{
- X /** save a list of options to the file **/
- X int length_so_far = 0;
- X struct addr_rec *alternate;
- X
- X if (list == NULL) return; /* nothing to do! */
- X
- X add_comment(iindex, fd);
- X
- X alternate = list; /* don't LOSE the top!! */
- X
- X length_so_far = strlen(save_info[iindex].name) + 4;
- X
- X fprintf(fd, "%s = ", save_info[iindex].name);
- X
- X while (alternate != NULL) {
- X if (strlen(alternate->address) + length_so_far > 78) {
- X fprintf(fd, "\n\t");
- X length_so_far = 8;
- X }
- X fprintf(fd, "%s ", alternate->address);
- X length_so_far += (strlen(alternate->address) + 3);
- X alternate = alternate->next;
- X }
- X fprintf(fd, "\n\n");
- X}
- X
- Xadd_comment(iindex, fd)
- Xint iindex;
- XFILE *fd;
- X{
- X /** get to and add the comment to the file **/
- X char buffer[SLEN];
- X
- X /** first off, add the comment from the comment file, if available **/
- X
- X if (save_info[iindex].offset > 0L) {
- X if (fseek(elminfo, save_info[iindex].offset, 0) == -1) {
- X dprint(1,(debugfile,
- X "** error %s seeking to %ld in elm-info file!\n",
- X error_name(errno), save_info[iindex].offset));
- X }
- X else while (fgets(buffer, SLEN, elminfo) != NULL) {
- X if (buffer[0] != '#')
- X break;
- X else
- X fprintf(fd, "%s", buffer);
- X }
- X }
- X}
- X
- Xbuild_offset_table(elminfo_fd)
- XFILE *elminfo_fd;
- X{
- X /** read in the info file and build the table of offsets.
- X This is a rather laborious puppy, but at least we can
- X do a binary search through the array for each element and
- X then we have it all at once!
- X **/
- X
- X char line_buffer[SLEN];
- X
- X while (fgets(line_buffer, SLEN, elminfo_fd) != NULL) {
- X if (strlen(line_buffer) > 1)
- X if (line_buffer[0] != '#' && !whitespace(line_buffer[0])) {
- X no_ret(line_buffer);
- X if (find_and_store_loc(line_buffer, ftell(elminfo_fd))) {
- X dprint(1, (debugfile,"** Couldn't find and store \"%s\" **\n",
- X line_buffer));
- X }
- X }
- X }
- X}
- X
- Xfind_and_store_loc(name, offset)
- Xchar *name;
- Xlong offset;
- X{
- X /** given the name and offset, find it in the table and store it **/
- X
- X int first = 0, last, middle, compare;
- X
- X last = NUMBER_OF_SAVEABLE_OPTIONS;
- X
- X while (first <= last) {
- X
- X middle = (first+last) / 2;
- X
- X if ((compare = strcmp(name, save_info[middle].name)) < 0) /* a < b */
- X last = middle - 1;
- X else if (compare == 0) { /* a = b */
- X save_info[middle].offset = offset;
- X return(0);
- X }
- X else /* greater */ /* a > b */
- X first = middle + 1;
- X }
- X
- X return(-1);
- X}
- SHAR_EOF
- chmod 0444 src/save_opts.c || echo "restore of src/save_opts.c fails"
- echo "x - extracting src/savecopy.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/savecopy.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: savecopy.c,v 4.1 90/04/28 22:44:02 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: savecopy.c,v $
- X * Revision 4.1 90/04/28 22:44:02 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** Save a copy of the specified message in a folder.
- X
- X**/
- X
- X#include "headers.h"
- X#ifdef I_TIME
- X# include <time.h>
- X#endif
- X#ifdef I_SYSTIME
- X# include <sys/time.h>
- X#endif
- X
- X#include <errno.h>
- X
- Xchar *format_long();
- Xchar *error_name(), *error_description();
- Xchar *ctime();
- X
- Xextern char in_reply_to[SLEN]; /* In-Reply-To: string */
- Xextern int errno;
- X
- Xchar *strcat(), *strcpy();
- Xunsigned long sleep();
- Xlong time();
- X
- Xsave_copy(to, cc, bcc, filename, copy_file, form)
- Xchar *to, *cc, *bcc, *filename, *copy_file;
- Xint form;
- X{
- X /** This routine appends a copy of the outgoing message to the
- X file specified. **/
- X
- X FILE *save, /* file id for file to save to */
- X *message, /* file id for file with message body */
- X *write_header_info();
- X char buffer[SLEN], /* read buffer */
- X savename[SLEN]; /* name of file saving into */
- X
- X
- X /* presume copy_file is okay as is for now */
- X strcpy(savename, copy_file);
- X
- X /* if save-by-name wanted */
- X if((strcmp(copy_file, "=") == 0) || (strcmp(copy_file, "=?") == 0)) {
- X
- X get_return_name(to, buffer, TRUE); /* determine 'to' login */
- X if (strlen(buffer) == 0) {
- X
- X /* can't get file name from 'to' -- use sent_mail instead */
- X dprint(3, (debugfile,
- X "Warning: get_return_name couldn't break down %s\n", to));
- X error1(
- X"Cannot determine `to' name to save by! Saving to \"sent\" folder %s instead.",
- X sent_mail);
- X strcpy(savename, "<");
- X sleep(3);
- X } else
- X sprintf(savename, "=%s", buffer); /* good! */
- X }
- X
- X expand_filename(savename, TRUE); /* expand special chars */
- X
- X /* If saving conditionally by logname but folder doesn't exist
- X * save to sent folder instead. */
- X if((strcmp(copy_file, "=?") == 0)
- X && (access(savename, ACCESS_EXISTS) != 0)) {
- X dprint(5, (debugfile,
- X "Conditional save by name: file %s doesn't exist - using \"<\".\n",
- X savename));
- X strcpy(savename, "<");
- X expand_filename(savename, TRUE);
- X }
- X
- X if ((errno = can_open(savename, "a"))) {
- X dprint(2, (debugfile,
- X "Error: attempt to autosave to a file that can't be appended to!\n"));
- X dprint(2, (debugfile, "\tfilename = \"%s\"\n", savename));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X
- X /* Lets try sent_mail before giving up */
- X if(strcmp(sent_mail, savename) == 0) {
- X /* we are ALREADY using sent_mail! */
- X error1("Cannot save to %s!", savename);
- X sleep(3);
- X return(FALSE);
- X }
- X
- X if ((errno = can_open(sent_mail, "a"))) {
- X dprint(2, (debugfile,
- X "Error: attempt to autosave to a file that can't be appended to!\n"));
- X dprint(2, (debugfile, "\tfilename = \"%s\"\n", sent_mail));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error2("Cannot save to %s nor to \"sent\" folder %s!",
- X savename, sent_mail);
- X sleep(3);
- X return(FALSE);
- X }
- X error2("Cannot save to %s! Saving to \"sent\" folder %s instead.",
- X savename, sent_mail);
- X sleep(3);
- X strcpy(savename, sent_mail);
- X }
- X
- X save_file_stats(savename);
- X
- X /* Write header */
- X if ((save = write_header_info(savename, to, cc, bcc,
- X form == YES, TRUE)) == NULL)
- X return(FALSE);
- X
- X /* Now add file with message as handed to mailer */
- X if ((message = fopen(filename, "r")) == NULL) {
- X fclose(save);
- X dprint(1, (debugfile,
- X "Error: Couldn't read folder %s (save_copy)\n", filename));
- X dprint(1, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't read folder %s!", filename);
- X sleep(3);
- X return(FALSE);
- X }
- X
- X copy_message_across(message, save, TRUE);
- X
- X
- X fclose(save);
- X fclose(message);
- X
- X restore_file_stats(savename);
- X
- X return(TRUE);
- X}
- Xchar *
- Xcf_english(fn)
- Xchar *fn;
- X{
- X /** Return "English" expansion for special copy file name abbreviations
- X or just the file name **/
- X
- X if(!*fn)
- X return("<no save>");
- X else if(!fn[1]) {
- X if(*fn == '=')
- X return("<unconditionally save by name>");
- X else if(*fn == '<')
- X return("<\"sent\" folder>");
- X } else if ((fn[0] == '=') && (fn[1] == '?'))
- X return("<conditionally save by name>");
- X
- X return(fn);
- X}
- X
- X#define NCF_PROMPT "Save copy in (use '?' for help/to list folders): "
- Xint
- Xname_copy_file(fn)
- Xchar *fn;
- X{
- X /** Prompt user for name of file for saving copy of outbound msg to.
- X Return true if we need a redraw. **/
- X
- X int redraw = 0; /* set when we ask for help = need redraw */
- X char buffer[SLEN], origbuffer[SLEN];
- X static char helpmsg[LONG_STRING];
- X
- X /* expand passed copy file name into English */
- X strcpy(buffer, cf_english(fn));
- X
- X /* prepare screen with instructions */
- X MoveCursor(LINES-2, 0);
- X CleartoEOS();
- X PutLine0(LINES-2, 0, NCF_PROMPT);
- X
- X while(1) {
- X
- X /* get file name from user input */
- X strcpy(origbuffer, buffer);
- X optionally_enter(buffer, LINES-2, strlen(NCF_PROMPT), FALSE, FALSE);
- X
- X if(strcmp(buffer, "?") != 0) { /* got what we wanted - non-help choice */
- X
- X if(strcmp(origbuffer, buffer) != 0)
- X /* user changed from our English expansion
- X * so we'd better copy user input to fn
- X */
- X strcpy(fn, buffer);
- X
- X /* else user presumably left our English expansion - no change in fn */
- X
- X /* display English expansion of new user input a while */
- X PutLine1(LINES-2, strlen(NCF_PROMPT), cf_english(fn));
- X MoveCursor(LINES, 0);
- X sleep(1);
- X MoveCursor(LINES-2, 0);
- X CleartoEOS();
- X
- X return(redraw);
- X }
- X
- X /* give help and list folders */
- X redraw = TRUE;
- X if(!*helpmsg) /* help message not yet formulated */
- X sprintf(helpmsg,
- X "\n\r%s\n\r%s%s%s\n\r%s\n\r%s\n\r%s\n\r%s\n\r%s\n\r\n\r",
- X "Enter: <nothing> to not save a copy of the message,",
- X " '<' to save in your \"sent\" folder (", sent_mail, "),",
- X " '=' to save by name (the folder name depends on whom the",
- X " message is to, in the end),",
- X " '=?' to save by name if the folder already exists,",
- X " and if not, to your \"sent\" folder,",
- X " or a filename (a leading '=' denotes your folder directory).");
- X
- X list_folders(4, helpmsg);
- X PutLine0(LINES-2, 0, NCF_PROMPT);
- X
- X /* restore as default to English version of the passed copy file name */
- X strcpy(buffer, cf_english(fn));
- X
- X }
- X}
- SHAR_EOF
- chmod 0444 src/savecopy.c || echo "restore of src/savecopy.c fails"
- echo "x - extracting src/screen.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/screen.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: screen.c,v 4.1 90/04/28 22:44:04 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: screen.c,v $
- X * Revision 4.1 90/04/28 22:44:04 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** screen display routines for ELM program
- X
- X**/
- X
- X#include "headers.h"
- X
- X#define minimum(a,b) ((a) < (b) ? (a) : (b))
- X
- Xstatic int last_current = -1;
- X
- Xchar *strcpy(), *strncpy(), *nameof(), *show_status(), *index();
- X
- Xextern char version_buff[];
- X
- Xshowscreen()
- X{
- X
- X ClearScreen();
- X
- X update_title();
- X
- X last_header_page = -1; /* force a redraw regardless */
- X show_headers();
- X
- X if (mini_menu)
- X show_menu();
- X
- X show_last_error();
- X
- X if (hp_terminal)
- X define_softkeys(MAIN);
- X}
- X
- Xupdate_title()
- X{
- X /** display a new title line, probably due to new mail arriving **/
- X
- X char buffer[SLEN];
- X
- X if (selected)
- X sprintf(buffer,
- X "%s is '%s' with %d shown out of %d [ELM %s]",
- X (folder_type == SPOOL ? "Mailbox" : "Folder"),
- X nameof(cur_folder), selected, message_count, version_buff);
- X else
- X sprintf(buffer, "%s is '%s' with %d message%s [ELM %s]",
- X (folder_type == SPOOL ? "Mailbox" : "Folder"),
- X nameof(cur_folder), message_count,
- X plural(message_count), version_buff);
- X
- X ClearLine(1);
- X
- X Centerline(1, buffer);
- X}
- X
- Xshow_menu()
- X{
- X /** write main system menu... **/
- X
- X if (user_level == 0) { /* a rank beginner. Give less options */
- X Centerline(LINES-7,
- X "You can use any of the following commands by pressing the first character;");
- X Centerline(LINES-6,
- X"d)elete or u)ndelete mail, m)ail a message, r)eply or f)orward mail, q)uit");
- X Centerline(LINES-5,
- X "To read a message, press <return>. j = move down, k = move up, ? = help");
- X } else {
- X Centerline(LINES-7,
- X "|=pipe, !=shell, ?=help, <n>=set current to n, /=search pattern");
- X Centerline(LINES-6,
- X"a)lias, C)opy, c)hange folder, d)elete, e)dit, f)orward, g)roup reply, m)ail,"
- X);
- X Centerline(LINES-5,
- X "n)ext, o)ptions, p)rint, q)uit, r)eply, s)ave, t)ag, u)ndelete, or e(x)it");
- X }
- X}
- X
- Xint
- Xshow_headers()
- X{
- X /** Display page of headers (10) if present. First check to
- X ensure that header_page is in bounds, fixing silently if not.
- X If out of bounds, return zero, else return non-zero
- X Modified to only show headers that are "visible" to ze human
- X person using ze program, eh?
- X **/
- X
- X register int this_msg = 0, line = 4, last = 0, last_line,
- X displayed = 0, using_to;
- X char newfrom[SLEN], buffer[SLEN];
- X
- X if (fix_header_page())
- X return(FALSE);
- X
- X if (selected) {
- X if ((header_page*headers_per_page) > selected)
- X return(FALSE); /* too far! too far! */
- X
- X this_msg = visible_to_index(header_page * headers_per_page + 1);
- X displayed = header_page * headers_per_page;
- X
- X last = displayed+headers_per_page;
- X
- X }
- X else {
- X if (header_page == last_header_page) /* nothing to do! */
- X return(FALSE);
- X
- X /** compute last header to display **/
- X
- X this_msg = header_page * headers_per_page;
- X last = this_msg + (headers_per_page - 1);
- X }
- X
- X if (last >= message_count) last = message_count-1;
- X
- X /** Okay, now let's show the header page! **/
- X
- X ClearLine(line); /* Clear the top line... */
- X
- X MoveCursor(line, 0); /* and move back to the top of the page... */
- X
- X while ((selected && displayed < last) || this_msg <= last) {
- X using_to = tail_of(headers[this_msg]->from, newfrom,
- X headers[this_msg]->to);
- X
- X if (this_msg == current-1)
- X build_header_line(buffer, headers[this_msg], this_msg+1,
- X TRUE, newfrom, using_to);
- X else
- X build_header_line(buffer, headers[this_msg],
- X this_msg+1, FALSE, newfrom, using_to);
- X if (selected)
- X displayed++;
- X
- X if (this_msg == current-1 && has_highlighting && ! arrow_cursor) {
- X StartInverse();
- X Write_to_screen("%s\n\r", 1, buffer); /* avoid '%' probs */
- X EndInverse();
- X } else
- X Write_to_screen("%s\n\r", 1, buffer); /* avoid '%' probs */
- X CleartoEOLN();
- X line++; /* for clearing up in a sec... */
- X
- X if (selected) {
- X if ((this_msg = next_message(this_msg, FALSE)) < 0)
- X break; /* GET OUTTA HERE! */
- X
- X /* the preceeding looks gross because we're using an INDEX
- X variable to pretend to be a "current" counter, and the
- X current counter is always 1 greater than the actual
- X index. Does that make sense??
- X */
- X }
- X else
- X this_msg++; /* even dumber... */
- X }
- X
- X /* clear unused lines */
- X
- X if (mini_menu)
- X last_line = LINES-8;
- X else
- X last_line = LINES-4;
- X
- X while (line < last_line) {
- X CleartoEOLN();
- X NewLine();
- X line++;
- X }
- X
- X display_central_message();
- X
- X last_current = current;
- X last_header_page = header_page;
- X
- X return(TRUE);
- X}
- X
- Xshow_current()
- X{
- X /** Show the new header, with all the usual checks **/
- X
- X register int first = 0, last = 0, last_line, new_line, using_to;
- X char newfrom[SLEN], old_buffer[SLEN], new_buffer[SLEN];
- X
- X (void) fix_header_page(); /* Who cares what it does? ;-) */
- X
- X /** compute the first and last header on this page **/
- X first = header_page * headers_per_page + 1;
- X last = first + (headers_per_page - 1);
- X
- X /* if not a full page adjust last to be the real last */
- X if (selected && last > selected)
- X last = selected;
- X if (!selected && last > message_count)
- X last = message_count;
- X
- X /** okay, now let's show the pointers... **/
- X
- X /** have we changed??? **/
- X if (current == last_current)
- X return;
- X
- X if (selected) {
- X last_line = ((compute_visible(last_current)-1) %
- X headers_per_page)+4;
- X new_line = ((compute_visible(current)-1) % headers_per_page)+4;
- X } else {
- X last_line = ((last_current-1) % headers_per_page)+4;
- X new_line = ((current-1) % headers_per_page)+4;
- X }
- X
- X if (has_highlighting && ! arrow_cursor) {
- X
- X using_to = tail_of(headers[current-1]->from, newfrom,
- X headers[current-1]->to);
- X build_header_line(new_buffer, headers[current-1], current,
- X TRUE, newfrom, using_to);
- X
- X /* clear last current if it's in proper range */
- X if (last_current > 0 /* not a dummy value */
- X && compute_visible(last_current) <= last
- X && compute_visible(last_current) >= first) {
- X
- X dprint(5, (debugfile,
- X "\nlast_current = %d ... clearing [1] before we add [2]\n",
- X last_current));
- X dprint(5, (debugfile, "first = %d, and last = %d\n\n",
- X first, last));
- X
- X using_to = tail_of(headers[last_current-1]->from, newfrom,
- X headers[last_current-1]->to);
- X build_header_line(old_buffer, headers[last_current-1],
- X last_current, FALSE, newfrom, using_to);
- X
- X ClearLine(last_line);
- X PutLine0(last_line, 0, old_buffer);
- X }
- X MoveCursor(new_line, 0);
- X StartInverse();
- X Write_to_screen("%s", 1, new_buffer);
- X EndInverse();
- X }
- X else {
- X if (on_page(last_current-1))
- X PutLine0(last_line,0," "); /* remove old pointer... */
- X if (on_page(current-1))
- X PutLine0(new_line, 0,"->");
- X }
- X
- X last_current = current;
- X}
- X
- Xbuild_header_line(buffer, entry, message_number, highlight, from, really_to)
- Xchar *buffer;
- Xstruct header_rec *entry;
- Xint message_number, highlight, really_to;
- Xchar *from;
- X{
- X /** Build in buffer the message header ... entry is the current
- X message entry, 'from' is a modified (displayable) from line,
- X 'highlight' is either TRUE or FALSE, and 'message_number'
- X is the number of the message.
- X **/
- X
- X /** Note: using 'strncpy' allows us to output as much of the
- X subject line as possible given the dimensions of the screen.
- X The key is that 'strncpy' returns a 'char *' to the string
- X that it is handing to the dummy variable! Neat, eh? **/
- X
- X int who_width = 18, subj_width;
- X char *dot = index(from, '.');
- X char *bang = index(from, '!');
- X
- X /* truncate 'from' to 18 characters -
- X * this includes the leading "To" if really_to is true.
- X * Note:
- X * 'from' is going to be of three forms
- X * - full name (truncate on the right for readability)
- X * - logname@machine (truncate on the right to preserve
- X * logname over machine name
- X * - machine!logname -- a more complex situation
- X * If this form doesn't fit, either machine
- X * or logname are long. If logname is long,
- X * we can stand to loose part of it, so we
- X * truncate on the right. If machine name is
- X * long, we'd better truncate on the left,
- X * to insure we get the logname. Now if the
- X * machine name is long, it will have "." in
- X * it.
- X * Therfore, we truncate on the left if there is a "." and a "!"
- X * in 'from', else we truncate on the right.
- X */
- X
- X /* Note that one huge sprintf() is too hard for some compilers. */
- X sprintf(buffer, "%s%s%c%-3d %3.3s %-2d ",
- X (highlight && arrow_cursor)? "->" : " ",
- X show_status(entry->status),
- X (entry->status & TAGGED? '+' : ' '),
- X message_number,
- X entry->month,
- X atoi(entry->day));
- X
- X /* show "To " in a way that it can never be truncated. */
- X if (really_to) {
- X strcat(buffer, "To ");
- X who_width -= 3;
- X }
- X
- X /* truncate 'from' on left if needed.
- X * sprintf will truncate on right afterward if needed. */
- X if ((strlen(from) > who_width) && dot && bang && (dot < bang)) {
- X from += (strlen(from) - who_width);
- X }
- X
- X /* Set the subject display width.
- X * If it is too long, truncate it to fit.
- X * If it is highlighted but not with the arrow cursor,
- X * expand it to fit so that the reverse video bar extends
- X * aesthetically the full length of the line.
- X */
- X if ((highlight && !arrow_cursor)
- X || (COLUMNS-44 < (subj_width =strlen(entry->subject))))
- X subj_width = COLUMNS-44;
- X
- X /* complete line with sender, length and subject. */
- X sprintf(buffer + strlen(buffer), "%-*.*s (%d) %s%-*.*s",
- X /* give max and min width parameters for 'from' */
- X who_width,
- X who_width,
- X from,
- X
- X entry->lines,
- X (entry->lines / 1000 > 0? "" : /* spacing the */
- X entry->lines / 100 > 0? " " : /* same for the */
- X entry->lines / 10 > 0? " " : /* lines in () */
- X " "), /* [wierd] */
- X
- X subj_width, subj_width, entry->subject);
- X}
- X
- Xint
- Xfix_header_page()
- X{
- X /** this routine will check and ensure that the current header
- X page being displayed contains messages! It will silently
- X fix 'header-page' if wrong. Returns TRUE if changed. **/
- X
- X int last_page, old_header;
- X
- X old_header = header_page;
- X
- X last_page = (int) ((message_count-1) / headers_per_page);
- X
- X if (header_page > last_page)
- X header_page = last_page;
- X else if (header_page < 0)
- X header_page = 0;
- X
- X return(old_header != header_page);
- X}
- X
- Xint
- Xon_page(message)
- Xint message;
- X{
- X /** Returns true iff the specified message is on the displayed page. **/
- X
- X if (selected) message = compute_visible(message);
- X
- X if (message >= header_page * headers_per_page)
- X if (message < ((header_page+1) * headers_per_page))
- X return(TRUE);
- X
- X return(FALSE);
- X}
- X
- Xchar *show_status(status)
- Xint status;
- X{
- X /** This routine returns a pair of characters indicative of
- X the status of this message. The first character represents
- X the interim status of the message (e.g. the status within
- X the mail system):
- X
- X E = Expired message
- X N = New message
- X O = Unread old message dsi mailx emulation addition
- X D = Deleted message
- X _ = (space) default
- X
- X and the second represents the permanent attributes of the
- X message:
- X
- X C = Company Confidential message
- X U = Urgent (or Priority) message
- X P = Private message
- X A = Action associated with message
- X F = Form letter
- X _ = (space) default
- X **/
- X
- X static char mybuffer[3];
- X
- X /** the first character, please **/
- X
- X if (status & DELETED) mybuffer[0] = 'D';
- X else if (status & EXPIRED) mybuffer[0] = 'E';
- X else if (status & NEW) mybuffer[0] = 'N';
- X else if (status & UNREAD) mybuffer[0] = 'O';
- X else mybuffer[0] = ' ';
- X
- X /** and the second... **/
- X
- X if (status & CONFIDENTIAL) mybuffer[1] = 'C';
- X else if (status & URGENT) mybuffer[1] = 'U';
- X else if (status & PRIVATE) mybuffer[1] = 'P';
- X else if (status & ACTION) mybuffer[1] = 'A';
- X else if (status & FORM_LETTER) mybuffer[1] = 'F';
- X else mybuffer[1] = ' ';
- X
- X mybuffer[2] = '\0';
- X
- X return( (char *) mybuffer);
- X}
- SHAR_EOF
- chmod 0444 src/screen.c || echo "restore of src/screen.c fails"
- echo "x - extracting src/showmsg.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/showmsg.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: showmsg.c,v 4.1 90/04/28 22:44:06 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,v $
- X * Revision 4.1 90/04/28 22:44:06 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains all the routines needed to display the specified
- X message.
- X**/
- X
- X#include "headers.h"
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#ifdef BSD
- X# include <sys/wait.h>
- X# undef tolower
- X#endif
- X
- Xextern int errno;
- X
- Xchar *error_name(), *strcat(), *strcpy();
- Xvoid _exit();
- X
- Xint memory_lock = FALSE; /* is it available?? */
- Xint pipe_abort = FALSE; /* did we receive a SIGNAL(SIGPIPE)? */
- X
- XFILE *pipe_wr_fp; /* file pointer to write to external pager */
- Xextern int lines_displayed, /* defined in "builtin" */
- X lines_put_on_screen; /* ditto too! */
- X
- Xint
- Xshow_msg(number)
- Xint number;
- X{
- X /*** Display number'th message. Get starting and ending lines
- X of message from headers data structure, then fly through
- X the file, displaying only those lines that are between the
- X two!
- X
- X Return 0 to return to the index screen or a character entered
- X by the user to initiate a command without returning to
- X the index screen (to be processed via process_showmsg_cmd()).
- X ***/
- X
- X char title1[SLEN], title2[SLEN], title3[SLEN], titlebuf[SLEN];
- X char who[LONG_STRING], buffer[VERY_LONG_STRING];
- X#if defined(BSD) && !defined(WEXITSTATUS)
- X union wait wait_stat;
- X#else
- X int wait_stat;
- X#endif
- X
- X int crypted = 0; /* encryption */
- X int weed_header, weeding_out = 0; /* weeding */
- X int using_to, /* misc use */
- X pipe_fd[2], /* pipe file descriptors */
- X new_pipe_fd, /* dup'ed pipe fil des */
- X lines, /* num lines in msg */
- X fork_ret, /* fork return value */
- X wait_ret, /* wait return value */
- X form_letter = FALSE, /* Form ltr? */
- X form_letter_section = 0, /* section */
- X padding = 0, /* counter */
- X builtin = FALSE, /* our pager? */
- X val = 0, /* return val */
- X buf_len; /* line length */
- X struct header_rec *current_header = headers[number-1];
- X
- X
- X lines = current_header->lines;
- X
- X dprint(4, (debugfile,"displaying %d lines from message %d using %s\n",
- X lines, number, pager));
- X
- X if (number > message_count || number < 1)
- X return(val);
- X
- X if(ison(current_header->status, NEW)) {
- X clearit(current_header->status, NEW); /* it's been read now! */
- X current_header->status_chgd = TRUE;
- X }
- X if(ison(current_header->status, UNREAD)) {
- X clearit(current_header->status, UNREAD); /* it's been read now! */
- X current_header->status_chgd = TRUE;
- X }
- X
- X memory_lock = FALSE;
- X
- X /* some explanation for that last one - We COULD use memory locking
- X to speed up the paging, but the action of "ClearScreen" on a screen
- X with memory lock turned on seems to vary considerably (amazingly so)
- X so it's safer to only allow memory lock to be a viable bit of
- X trickery when dumping text to the screen in scroll mode.
- X Philosophical arguments should be forwarded to Bruce at the
- X University of Walamazoo, Australia, via ACSNet *wry chuckle* */
- X
- X if (fseek(mailfile, current_header->offset, 0) == -1) {
- X dprint(1, (debugfile,
- X "Error: seek %d bytes into file, errno %s (show_message)\n",
- X current_header->offset, error_name(errno)));
- X error2("ELM failed seeking %d bytes into file (%s).",
- X current_header->offset, error_name(errno));
- X return(val);
- X }
- X if(current_header->encrypted)
- X getkey(OFF);
- X
- X if(builtin=(first_word(pager,"builtin")||first_word(pager,"internal")))
- X
- X start_builtin(lines);
- X
- X else {
- X
- X /* put terminal out of raw mode so external pager has normal env */
- X Raw(OFF);
- X
- X /* create pipe for external pager and fork */
- X
- X if(pipe(pipe_fd) == -1) {
- X dprint(1, (debugfile, "Error: pipe failed, errno %s (show_msg)\n",
- X error_name(errno)));
- X error1("Could not prepare for external pager(pipe()-%s).",
- X error_name(errno));
- X Raw(ON);
- X return(val);
- X }
- X
- X if((fork_ret = fork()) == -1) {
- X
- X dprint(1, (debugfile, "Error: fork failed, errno %s (show_msg)\n",
- X error_name(errno)));
- X error1("Could not prepare for external pager(fork()-%s).",
- X error_name(errno));
- X Raw(ON);
- X return(val);
- X
- X } else if (fork_ret == 0) {
- X
- X /* child fork */
- X
- X /* close write-only pipe fd and fit read-only pipe fd to stdin */
- X
- X close(pipe_fd[1]);
- X close(fileno(stdin));
- X if((new_pipe_fd = dup(pipe_fd[0])) == -1) {
- X dprint(1, (debugfile, "Error: dup failed, errno %s (show_msg)\n",
- X error_name(errno)));
- X error1("Could not prepare for external pager(dup()-%s).",
- X error_name(errno));
- X _exit(errno);
- X }
- X close(pipe_fd[0]); /* original pipe fd no longer needed */
- X
- X /* use stdio on new pipe fd */
- X if(fdopen(new_pipe_fd, "r") == NULL) {
- X dprint(1,
- X (debugfile, "Error: child fdopen failed, errno %s (show_msg)\n",
- X error_name(errno)));
- X error1("Could not prepare for external pager(child fdopen()-%s).",
- X error_name(errno));
- X _exit(errno);
- X }
- X
- X /* now execute pager and exit */
- X
- X /* system_call() will return user to user's normal permissions.
- X * This is what makes this pipe secure - user won't have elm's
- X * special setgid permissions (if so configured) and will only
- X * be able to execute a pager that user normally has permission
- X * to execute */
- X
- X _exit(system_call(pager, SH, TRUE, TRUE));
- X
- X } /* else this is the parent fork */
- X
- X /* close read-only pipe fd and do write-only with stdio */
- X close(pipe_fd[0]);
- X
- X if((pipe_wr_fp = fdopen(pipe_fd[1], "w")) == NULL) {
- X dprint(1,
- X (debugfile, "Error: parent fdopen failed, errno %s (show_msg)\n",
- X error_name(errno)));
- X error1("Could not prepare for external pager(parent fdopen()-%s).",
- X error_name(errno));
- X
- X /* Failure - must close pipe and wait for child */
- X close(pipe_fd[1]);
- X while ((wait_ret = wait(&wait_stat)) != fork_ret && wait_ret!= -1)
- X ;
- X
- X Raw(OFF);
- X return(val); /* pager may have already touched the screen */
- X }
- X
- X /* and that's it! */
- X lines_displayed = 0;
- X }
- X
- X ClearScreen();
- X
- X if (cursor_control) transmit_functions(OFF);
- X
- X pipe_abort = FALSE;
- X
- X if (form_letter = (current_header->status&FORM_LETTER)) {
- X if (filter)
- X form_letter_section = 1; /* initialize to section 1 */
- X }
- X
- X if (title_messages && filter) {
- X
- X using_to =
- X tail_of(current_header->from, who, current_header->to);
- X
- X sprintf(title1, "%s %d/%d ",
- X headers[current-1]->status & DELETED ? "[deleted]" :
- X form_letter ? "Form": "Message",
- X number, message_count);
- X sprintf(title2, "%s %s", using_to? "To" : "From", who);
- X sprintf(title3, " %s %s '%d at %s %s",
- X current_header->month, current_header->day,
- X atoi(current_header->year), current_header->time,
- X current_header->time_zone);
- X
- X /* truncate or pad title2 portion on the right
- X * so that line fits exactly */
- X padding =
- X COLUMNS -
- X (strlen(title1) + (buf_len=strlen(title2)) + strlen(title3));
- X
- X sprintf(titlebuf, "%s%-*.*s%s\n", title1, buf_len+padding,
- X buf_len+padding, title2, title3);
- X
- X if (builtin)
- X display_line(titlebuf);
- X else
- X fprintf(pipe_wr_fp, "%s", titlebuf);
- X
- X /** if there's a subject, let's output it next,
- X centered if it fits on a single line. **/
- X
- X if ((buf_len = strlen(current_header->subject)) > 0 &&
- X matches_weedlist("Subject:")) {
- X padding = (buf_len < COLUMNS ? COLUMNS - buf_len : 0);
- X sprintf(buffer, "%*s%s\n", padding/2, "", current_header->subject);
- X } else
- X strcpy(buffer, "\n");
- X
- X if (builtin)
- X display_line(buffer);
- X else
- X fprintf(pipe_wr_fp, "%s", buffer);
- X
- X /** was this message address to us? if not, then to whom? **/
- X
- X if (! using_to && matches_weedlist("To:") && filter &&
- X strcmp(current_header->to,username) != 0 &&
- X strlen(current_header->to) > 0) {
- X if (strlen(current_header->to) > 60)
- X sprintf(buffer, "%s(message addressed to %.60s)\n",
- X strlen(current_header->subject) > 0 ? "\n" : "",
- X current_header->to);
- X else
- X sprintf(buffer, "%s(message addressed to %s)\n",
- X strlen(current_header->subject) > 0 ? "\n" : "",
- X current_header->to);
- X if (builtin)
- X display_line(buffer);
- X else
- X fprintf(pipe_wr_fp, "%s", buffer);
- X }
- X
- X /** The test above is: if we didn't originally send the mail
- X (e.g. we're not reading "mail.sent") AND the user is currently
- X weeding out the "To:" line (otherwise they'll get it twice!)
- X AND the user is actually weeding out headers AND the message
- X wasn't addressed to the user AND the 'to' address is non-zero
- X (consider what happens when the message doesn't HAVE a "To:"
- X line...the value is NULL but it doesn't match the username
- X either. We don't want to display something ugly like
- X "(message addressed to )" which will just clutter up the
- X screen!).
- X
- X And you thought programming was EASY!!!!
- X **/
- X
- X /** one more friendly thing - output a line indicating what sort
- X of status the message has (e.g. Urgent etc). Mostly added
- X for X.400 support, this is nonetheless generally useful to
- X include...
- X **/
- X
- X buffer[0] = '\0';
- X
- X /* we want to flag Urgent, Confidential, Private and Expired tags */
- X
- X if (current_header->status & PRIVATE)
- X strcpy(buffer, "\n(** This message is tagged Private");
- X else if (current_header->status & CONFIDENTIAL)
- X strcpy(buffer, "\n(** This message is tagged Company Confidential");
- X
- X if (current_header->status & URGENT) {
- X if (buffer[0] == '\0')
- X strcpy(buffer, "\n(** This message is tagged Urgent");
- X else if (current_header->status & EXPIRED)
- X strcat(buffer, ", Urgent");
- X else
- X strcat(buffer, " and Urgent");
- X }
- X
- X if (current_header->status & EXPIRED) {
- X if (buffer[0] == '\0')
- X strcpy(buffer, "\n(** This message has Expired");
- X else
- X strcat(buffer, ", and has Expired");
- X }
- X
- X if (buffer[0] != '\0') {
- X strcat(buffer, " **)\n");
- X if (builtin)
- X display_line(buffer);
- X else
- X fprintf(pipe_wr_fp, buffer);
- X }
- X
- X if (builtin) /* this is for a one-line blank */
- X display_line("\n"); /* separator between the title */
- X else /* stuff and the actual message */
- X fprintf(pipe_wr_fp, "\n"); /* we're trying to display */
- X
- X }
- X
- X weed_header = filter; /* allow us to change it after header */
- X
- X while (lines > 0 && pipe_abort == FALSE) {
- X
- X if (fgets(buffer, VERY_LONG_STRING, mailfile) == NULL) {
- X
- X dprint(1, (debugfile,
- X "Premature end of file! Lines left = %d msg = %s (show_msg)\n",
- X lines, number));
- X
- X error("Premature end of file!");
- SHAR_EOF
- echo "End of part 21"
- echo "File src/showmsg.c is continued in part 22"
- echo "22" > s2_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-