home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i083: ELM mail syste, release 2.3, Part25/26
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: dcc30b68 9a84483e f0b5046f 25130268
-
- Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
- Posting-number: Volume 22, Issue 83
- Archive-name: elm2.3/part25
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # this is part 25 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file utils/from.c continued
- #
- CurArch=25
- 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 utils/from.c"
- sed 's/^X//' << 'SHAR_EOF' >> utils/from.c
- X temp[i] = '\0';
- X temp++;
- X }
- X
- X /* if anything is left, let's change 'from' value! */
- X
- X if (strlen(temp) > 0)
- X strcpy(newfrom, temp);
- X }
- 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}
- SHAR_EOF
- echo "File utils/from.c is complete"
- chmod 0444 utils/from.c || echo "restore of utils/from.c fails"
- echo "x - extracting utils/listalias.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/listalias.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: listalias.c,v 4.1 90/04/28 22:44:42 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: listalias.c,v $
- X * Revision 4.1 90/04/28 22:44:42 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** Program that lists all the available aliases. This one uses the pipe
- X command, feeding the stuff to egrep then sort, or just sort.
- X
- X**/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X
- X#include "defs.h"
- X#include "sysdefs.h"
- X
- X#ifdef BSD
- X FILE *popen();
- X#endif
- X
- Xchar *getenv();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *datafile, *fd_pipe;
- X struct alias_rec hash_record;
- X int hashfile, count = 0;
- X char buffer[SLEN], fd_hash[SLEN],
- X fd_data[SLEN], *home;
- X
- X if (argc > 2) {
- X printf("Usage: listalias <optional-regular-expression>\n");
- X exit(1);
- X }
- X
- X home = getenv("HOME");
- X
- X sprintf(fd_hash, "%s/%s", home, ALIAS_HASH);
- X sprintf(fd_data, "%s/%s", home, ALIAS_DATA);
- X
- X if (argc > 1)
- X sprintf(buffer, "egrep \"%s\" | sort", argv[1]);
- X else
- X sprintf(buffer, "sort");
- X
- X if ((fd_pipe = popen(buffer, "w")) == NULL) {
- X if (argc > 1)
- X printf("cannot open pipe to egrep program for expressions!\n");
- X fd_pipe = stdout;
- X }
- X
- X do {
- X
- X if ((hashfile = open(fd_hash, O_RDONLY)) > 0) {
- X if ((datafile = fopen(fd_data, "r")) == NULL) {
- X printf("Opened %s hash file, but couldn't open data file!\n",
- X count? "system" : "user");
- X goto next_file;
- X }
- X
- X /** Otherwise let us continue... **/
- X
- X while (read(hashfile, &hash_record, sizeof (hash_record)) != 0) {
- X if (strlen(hash_record.name) > 0) {
- X fseek(datafile, ntohl(hash_record.byte), 0L);
- X fgets(buffer, SLEN, datafile);
- X fprintf(fd_pipe, "%-15s %s", hash_record.name, buffer);
- X }
- X }
- X }
- X
- Xnext_file: strcpy(fd_hash, system_hash_file);
- X strcpy(fd_data, system_data_file);
- X
- X } while (++count < 2);
- X
- X pclose(fd_pipe);
- X
- X exit(0);
- X}
- SHAR_EOF
- chmod 0444 utils/listalias.c || echo "restore of utils/listalias.c fails"
- echo "x - extracting utils/mailrc.awk (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/mailrc.awk &&
- X#
- X# @(#)$Id: mailrc.awk,v 4.1 90/04/28 22:44:44 syd Exp $
- X# Copyright (c) 1986, 1987 Dave Taylor
- X# Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X# Bug reports, patches, comments, suggestions should be sent to:
- X#
- X# Syd Weinstein, Elm Coordinator - elm@DSI.COM
- X# dsinc!elm
- X#
- X# $Log: mailrc.awk,v $
- X# Revision 4.1 90/04/28 22:44:44 syd
- X# checkin of Elm 2.3 as of Release PL0
- X#
- X#
- X
- X
- XBEGIN {
- X print "# MSG alias_text file, from a .mailrc file..."
- X print ""
- X }
- X
- Xnext_line == 1 {
- X
- X next_line = 0;
- X group = ""
- X for (i = 1; i <= NF; i++) {
- X if (i == NF && $i == "\\") sep = ""
- X else sep = ", "
- X
- X if ($i == "\\") {
- X group = sprintf("%s,", group)
- X next_line = 1;
- X }
- X else if (length(group) > 0)
- X group = sprintf("%s%s%s", group, sep, $i);
- X else
- X group = $i;
- X }
- X print "\t" group
- X
- X }
- X
- X$1 ~ /[Aa]lias|[Gg]roup/ {
- X
- X if ( NF == 3)
- X print $2 " = user alias = " $3;
- X else {
- X group = ""
- X for (i = 3; i <= NF; i++) {
- X if (i == NF && $i == "\\") sep = ""
- X else sep = ", "
- X
- X if ($i == "\\") {
- X group = sprintf("%s,", group)
- X next_line = 1;
- X }
- X else if (length(group) > 0)
- X group = sprintf("%s%s%s", group, sep, $i);
- X else
- X group = $i;
- X }
- X print $2 " = group alias = " group;
- X }
- X }
- SHAR_EOF
- chmod 0444 utils/mailrc.awk || echo "restore of utils/mailrc.awk fails"
- echo "x - extracting utils/messages (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/messages &&
- X: Use /bin/sh
- X# messages: part of the Elm mail system
- X# @(#)$Id: messages,v 4.1 90/04/28 22:44:45 syd Exp $
- X
- Xif [ "$2" != "" ]; then
- X echo Usage: messages \{folder-name\} 1>&2
- X exit 1
- Xfi
- X
- Xif [ "$1" = "" ]; then
- X fname=$MAIL
- X optional="in your mailbox"
- Xelse
- X fname=$1
- X optional="in folder $1"
- Xfi
- X
- Xif [ -f "$fname" ]; then
- X mcount=`egrep -c "^From " $fname`
- Xelse
- X exit 0
- Xfi
- X
- Xif [ "$mcount" -eq 1 ]; then
- X echo There is $mcount message $optional.
- Xelse
- X echo There are $mcount messages $optional.
- Xfi
- X
- Xexit $mcount
- SHAR_EOF
- chmod 0444 utils/messages || echo "restore of utils/messages fails"
- echo "x - extracting utils/newalias.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/newalias.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: newalias.c,v 4.1 90/04/28 22:44:46 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: newalias.c,v $
- X * Revision 4.1 90/04/28 22:44:46 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** Install a new set of aliases for the 'Elm' mailer.
- X
- X If invoked with a specific filename, it assumes that
- X it is working with an individual users alias tables, and
- X generates the .alias.hash and .alias.data files in their
- X home directory.
- X If, however, it is invoked with no arguments, then
- X it assumes that the user is updating the system alias
- X file and uses the defaults for everything.
- X
- X The format for the input file is;
- X alias1, alias2, ... = username = address
- Xor alias1, alias2, ... = groupname= member, member, member, ...
- X member, member, member, ...
- X
- X**/
- X
- X#include <stdio.h>
- X#include "defs.h"
- X#include "sysdefs.h" /* ELM system definitions */
- X#include <ctype.h>
- X
- X#ifdef BSD
- X# include <sys/file.h>
- X# undef tolower
- X# undef toupper
- X#else
- X# include <fcntl.h>
- X#endif
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#define group(string) (strpbrk(string,", ") != NULL)
- X
- Xstruct alias_rec
- Xshash_table[MAX_SALIASES]; /* the actual hash table */
- X
- Xstruct alias_rec
- Xuhash_table[MAX_UALIASES]; /* the actual hash table */
- X
- Xint hash_table_loaded=0; /* is system table actually loaded? */
- X
- Xint buff_loaded; /* for file input overlap... */
- Xint error= 0; /* if errors, don't save! */
- Xint is_system=0; /* system file updating? */
- Xint count=0; /* how many aliases so far? */
- Xlong offset = 0L; /* data file line offset! */
- Xchar home[SLEN]; /* the users home directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *in, *data;
- X char inputname[SLEN], hashname[SLEN], dataname[SLEN];
- X char buffer[LONG_STRING];
- X int a, hash, count = 0, owner;
- X
- X for (a = 1; a < argc; ++a) {
- X if (strcmp(argv[a], "-g") == 0)
- X is_system = 1;
- X else {
- X printf("Usage: %s [-g]\n", argv[0]);
- X exit(1);
- X }
- X }
- X
- X if (is_system) { /* update system aliases */
- X printf("Updating the system alias file...\n");
- X
- X strcpy(inputname, system_text_file);
- X strcpy(hashname, system_hash_file);
- X strcpy(dataname, system_data_file);
- X init_table(shash_table, MAX_SALIASES);
- X }
- X else
- X printf("Updating your personal alias file...\n");
- X
- X if (! is_system) {
- X if (strcpy(home, getenv("HOME")) == NULL) {
- X printf("I'm confused - no HOME variable in environment!\n");
- X exit(1);
- X }
- X
- X sprintf(inputname, "%s/%s", home, ALIAS_TEXT);
- X sprintf(hashname, "%s/%s", home, ALIAS_HASH);
- X sprintf(dataname, "%s/%s", home, ALIAS_DATA);
- X
- X init_table(uhash_table, MAX_UALIASES);
- X
- X read_in_system(shash_table, sizeof shash_table);
- X }
- X
- X if ((in = fopen(inputname,"r")) == NULL) {
- X /** let's see if they have the files in the old place... **/
- X sprintf(buffer, "%s/.alias_text", home);
- X if (access(buffer, ACCESS_EXISTS) != -1) {
- X update_alias_file_locations();
- X in = fopen(inputname, "r");
- X }
- X else {
- X printf("Couldn't open %s for input!\n", inputname);
- X exit(1);
- X }
- X }
- X
- X if ((hash = open(hashname, O_WRONLY | O_CREAT, 0644)) == -1) {
- X printf("Couldn't open %s for output!\n", hashname);
- X exit(1);
- X }
- X
- X if ((data = fopen(dataname,"w")) == NULL) {
- X printf("Couldn't open %s for output!\n", dataname);
- X exit(1);
- X }
- X
- X buff_loaded = 0; /* file buffer empty right now! */
- X
- X while (get_alias(in, buffer) != -1) {
- X if (is_system)
- X put_alias(data, buffer, shash_table, MAX_SALIASES);
- X else
- X put_alias(data, buffer, uhash_table, MAX_UALIASES);
- X count++;
- X }
- X
- X if (error) {
- X printf("\n** Not saving tables! Please fix and re-run %s!\n",
- X argv[0]);
- X exit(1);
- X }
- X else {
- X if (is_system)
- X write(hash, shash_table, sizeof shash_table);
- X else
- X write(hash, uhash_table, sizeof uhash_table);
- X
- X close(hash);
- X fclose(data);
- X fclose(in);
- X
- X printf("Processed %d aliases\n", count);
- X exit(0);
- X }
- X}
- X
- Xint
- Xget_alias(file, buffer)
- XFILE *file;
- Xchar *buffer;
- X{
- X /* load buffer with the next complete alias from the file.
- X (this can include reading in multiple lines and appending
- X them all together!) Returns EOF after last entry in file.
- X
- X Lines that start with '#' are assumed to be comments and are
- X ignored. White space as the first field of a line is taken
- X to indicate that this line is a continuation of the previous. */
- X
- X static char mybuffer[SLEN];
- X int done = 0, first_read = 1;
- X
- X /** get the first line of the entry... **/
- X
- X buffer[0] = '\0'; /* zero out line */
- X
- X do {
- X if (get_line(file, mybuffer, first_read) == -1)
- X return(-1);
- X first_read = 0;
- X if (mybuffer[0] != '#')
- X strcpy(buffer, mybuffer);
- X } while (strlen(buffer) == 0);
- X
- X /** now read in the rest (if there is any!) **/
- X
- X do {
- X if (get_line(file, mybuffer, first_read) == -1) {
- X buff_loaded = 0; /* force a read next pass! */
- X return(0); /* okay. let's just hand 'buffer' back! */
- X }
- X done = (! whitespace(mybuffer[0]));
- X if (! done)
- X strcat(buffer, mybuffer);
- X done = (done && mybuffer[0] != '#');
- X } while (! done);
- X
- X return(0); /* no sweat! */
- X}
- X
- Xput_alias(data, buffer, table, size)
- XFILE *data;
- Xchar *buffer;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** break buffer down into three pieces: aliases, comment, and address.
- X Make the appropriate entries in the table (size)
- X **/
- X
- X char aliases[LONG_STRING], address[LONG_STRING];
- X char comment[LONG_STRING], c;
- X int first, last, i = 0, j = 0;
- X
- X remove_all(' ', TAB, buffer);
- X
- X for (i=0; buffer[i] != '=' && i < LONG_STRING; i++)
- X aliases[i] = buffer[i];
- X aliases[i] = '\0';
- X
- X for (i=strlen(buffer)-1; buffer[i] != '=' && i > 0; i--)
- X address[j++] = buffer[i];
- X address[j] = '\0';
- X
- X comment[0] = '\0'; /* default to nothing at all... */
- X
- X if ((first=strlen(aliases)+1) < (last=(strlen(buffer) - j))) {
- X extract_comment(comment, buffer, first, last);
- X }
- X
- X reverse(address);
- X
- X add_to_table(data, aliases, comment, address, table, size);
- X}
- X
- Xint
- Xget_line(file, buffer, first_line)
- XFILE *file;
- Xchar *buffer;
- Xint first_line;
- X{
- X /** read line from file. If first_line and buff_loaded,
- X then just return! **/
- X
- X int stat, len;
- X
- X if (first_line && buff_loaded) {
- X buff_loaded = 1;
- X return(0);
- X }
- X
- X buff_loaded = 1; /* we're going to get SOMETHING in the buffer */
- X
- X stat = fgets(buffer, SLEN, file) == NULL ? -1 : 0;
- X
- X if (stat != -1) {
- X len = strlen(buffer);
- X if (len > 0) {
- X if (buffer[len - 1] != '\n') {
- X printf("Line too long, split using continuation line format (starting line\nwith whitespace):\n%s\n\n", buffer);
- X exit(1);
- X }
- X }
- X no_ret(buffer);
- X }
- X
- X return(stat);
- X}
- X
- Xreverse(string)
- Xchar *string;
- X{
- X /** reverse the order of the characters in string...
- X uses a bubble-sort type of algorithm! **/
- X
- X register int f, l;
- X char c;
- X
- X f = 0;
- X l = strlen(string) - 1;
- X
- X while (f < l) {
- X c = string[f];
- X string[f] = string[l];
- X string[l] = c;
- X f++;
- X l--;
- X }
- X}
- X
- Xadd_to_table(data, aliases, comment, address, table, size)
- XFILE *data;
- Xchar *aliases, *comment, *address;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** add address + comment to datafile, incrementing offset count
- X (bytes), then for each alias in the aliases string, add to the
- X hash table, with the associated pointer value! **/
- X
- X static char buf[SLEN], *word, *s;
- X long additive = 1L;
- X
- X word = buf; /* use the allocated space! */
- X
- X for ( s = aliases ; *s != '\0' && (ok_alias_char(*s)||*s==',') ; ++s ) ;
- X if ( *s != '\0' ) {
- X printf("Error - character '%c' in alias '%s' is not supported.\n",
- X *s, aliases);
- X error++;
- X return;
- X }
- X
- X if (group(address)) {
- X check_group(address, aliases);
- X if (error) return; /* don't do work if we aren't to save it! */
- X fprintf(data, "!%s\n", address);
- X additive = 2L;
- X }
- X else {
- X if (error) return; /* don't do work if we aren't to save it! */
- X if (strlen(comment) > 0) {
- X fprintf(data, "%s (%s)\n", address, comment);
- X additive = (long) (strlen(comment) + 4);
- X }
- X else
- X fprintf(data, "%s\n", address, comment);
- X }
- X
- X while ((word = (char *) strtok(aliases,", ")) != NULL) {
- X add_to_hash_table(word, offset, table, size);
- X aliases = NULL; /* let's get ALL entries via 'strtok' */
- X count++;
- X }
- X
- X if ( is_system ? count > MAX_SALIASES-35 : count > MAX_UALIASES-21) {
- X printf("** Too many aliases in file! **\n");
- X error++;
- X }
- X
- X offset = (offset + (long) strlen(address) + additive);
- X}
- X
- Xremove_all(c1, c2, string)
- Xchar c1, c2, *string;
- X{
- X /* Remove all occurances of character 'c1' or 'c2' from the string.
- X Hacked (literally) to NOT remove ANY characters from within the
- X equals fields. This will only be used if the line contains TWO
- X equalss (and comments with equalss in them are the kiss of death!)
- X */
- X
- X char buffer[LONG_STRING];
- X register int i = 0, j = 0, first_equals = -1, last_equals = -1;
- X
- X for (i = 0; string[i] != '\0' && i < LONG_STRING; i++) {
- X if (string[i] != c1 && string[i] != c2)
- X buffer[j++] = string[i];
- X
- X if (first_equals == -1 && string[i] == '=') {
- X first_equals = i;
- X for (last_equals=strlen(string);string[last_equals] != '=';
- X last_equals--) ;
- X }
- X else if (i > first_equals && i < last_equals)
- X if (string[i] == c1 || string[i] == c2)
- X buffer[j++] = string[i];
- X }
- X
- X buffer[j] = '\0';
- X strcpy(string, buffer);
- X}
- X
- Xadd_to_hash_table(word, offset, table, size)
- Xchar *word;
- Xlong offset;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** add word and offset to current hash table. **/
- X register int loc;
- X
- X if (strlen(word) > 20) {
- X printf("Bad alias name: %s. Too long.\n", word);
- X exit(1);
- X }
- X
- X loc = hash_it(word, size);
- X
- X while (table[loc].name[0] != '\0' && stricmp(table[loc].name,word) != 0)
- X loc = (loc + 1) % size;
- X
- X if (table[loc].name[0] == '\0') {
- X strcpy(table[loc].name, word);
- X table[loc].byte = htonl(offset);
- X }
- X else
- X printf("** Duplicate alias '%s' in file. Multiples ignored.\n",
- X word);
- X}
- X
- Xint
- Xstricmp(s1,s2)
- Xregister char *s1, *s2;
- X{
- X /* case insensitive comparison */
- X register int d;
- X for (;;) {
- X d = ( isupper(*s1) ? tolower(*s1) : *s1 )
- X - ( isupper(*s2) ? tolower(*s2) : *s2 ) ;
- X if ( d != 0 || *s1 == '\0' || *s2 == '\0' )
- X return d;
- X ++s1;
- X ++s2;
- X }
- X /*NOTREACHED*/
- X}
- X
- Xint
- Xhash_it(string, table_size)
- Xregister char *string;
- Xint table_size;
- X{
- X /** compute the hash function of the string, returning
- X it (mod table_size) **/
- X
- X register int sum = 0;
- X for ( ; *string != '\0' ; ++string )
- X sum += (int) ( isupper(*string) ? tolower(*string) : *string );
- X return(sum % table_size);
- X}
- X
- X
- Xinit_table(table, size)
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** initialize hash table! **/
- X
- X register int i;
- X
- X for (i=0; i < size; i++)
- X table[i].name[0] = '\0';
- X}
- X
- Xread_in_system(table, size)
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** read in the system hash table...to check for group aliases
- X from the user alias file (to ensure that there are no names
- X in the user group files that are not purely contained within
- X either alias table) **/
- X
- X int fd;
- X char fname[SLEN];
- X
- X sprintf(fname, "%s/%s", mailhome, ALIAS_HASH);
- X
- X if ((fd = open(fname, O_RDONLY)) == -1)
- X return; /* no sweat: flag 'hash_table_loaded' not set! */
- X
- X (void) read(fd, table, size);
- X close(fd);
- X hash_table_loaded++;
- X}
- X
- Xcheck_group(names, groupname)
- Xchar *names, *groupname;
- X{
- X /** one by one make sure each name in the group is defined
- X in either the system alias file or the user alias file.
- X This search is linearly dependent, so all group aliases
- X in the source file should appear LAST, after all the user
- X aliases! **/
- X
- X char *word, *bufptr, buffer[LONG_STRING];
- X int aliased;
- X
- X strcpy(buffer, names);
- X bufptr = (char *) buffer;
- X names[0] = '\0';
- X
- X while ((word = (char *) strtok(bufptr,", ")) != NULL) {
- X if (! (aliased = can_find(word)))
- X if (! valid_name(word)) {
- X error++;
- X printf("** Alias %s in group %s is bad!\n", word, groupname);
- X }
- X bufptr = NULL;
- X if (names[0])
- X strcat(names, ", ");
- X strcat(names, word);
- X }
- X}
- X
- Xint
- Xcan_find(name)
- Xchar *name;
- X{
- X /** find name in either hash table...use 'is_system' variable to
- X determine if we should look in both or just system.... **/
- X
- X register int loc;
- X
- X if (strlen(name) > 20) {
- X error++;
- X printf("** Bad alias name: %s. Too long.\n", name);
- X return(1); /* fake out: don't want 2 error messages! */
- X }
- X
- X /** system alias table... **/
- X if (hash_table_loaded || is_system) {
- X loc = hash_it(name, MAX_SALIASES);
- X
- X while (stricmp(name, shash_table[loc].name) != 0 &&
- X shash_table[loc].name[0] != '\0')
- X loc = (loc + 1) % MAX_SALIASES;
- X
- X if (stricmp(name, shash_table[loc].name) == 0)
- X return(1); /* found it! */
- X }
- X
- X if (! is_system) { /* okay! Let's check the user alias file! */
- X loc = hash_it(name, MAX_UALIASES);
- X
- X while (stricmp(name, uhash_table[loc].name) != 0 &&
- X uhash_table[loc].name[0] != '\0')
- X loc = (loc + 1) % MAX_UALIASES;
- X
- X if (stricmp(name, uhash_table[loc].name) == 0)
- X return(1); /* found it! */
- X }
- X
- X return(0);
- X}
- X
- Xextract_comment(comment, buffer, first, last)
- Xchar *comment, *buffer;
- Xint first, last;
- X{
- X /** Buffer contains a comment, located between the first and last
- X values. Copy that into 'comment', but remove leading and
- X trailing white space. Note also that it doesn't copy past
- X a comma, so `unpublishable' comments can be of the form;
- X dave: Dave Taylor, HP Labs : taylor@hplabs
- X and the output will be "taylor@hplabs (Dave Taylor)".
- X **/
- X
- X register int loc = 0;
- X
- X /** first off, skip the LEADING white space... **/
- X
- X while (whitespace(buffer[first])) first++;
- X
- X /** now let's backup the 'last' value until we hit a non-whitespace **/
- X
- X last -= 2; /* starts at ch AFTER equals.. */
- X while (whitespace(buffer[last])) last--;
- X
- X /** now a final check to make sure we're still talking about a
- X reasonable string (rather than a "joe :: joe@dec" type string) **/
- X
- X if (first < last) {
- X /* one more check - let's find the comma, if present... */
- X for (loc=first; loc < last; loc++)
- X if (buffer[loc] == ',') {
- X last = loc-1;
- X break;
- X }
- X loc = 0;
- X while (first <= last)
- X comment[loc++] = buffer[first++];
- X comment[loc] = '\0';
- X }
- X}
- X
- Xupdate_alias_file_locations()
- X{
- X /** a short-term routine to ensure that the data files are
- X moved into the correct directory... **/
- X
- X char source[SLEN], dest[SLEN];
- X
- X /** first let's create the directory if it ain't there... **/
- X
- X sprintf(source, "%s/.elm", home);
- X
- X /** Some systems don't have a mkdir call - how inconvienient! **/
- X#ifdef MKDIR
- X (void) mkdir(source, 0700);
- X#else
- X system("mkdir $HOME/.elm");
- X system("chmod 700 $HOME/.elm");
- X#endif /* MKDIR */
- X
- X /** now *link* the files... **/
- X
- X sprintf(source, "%s/.alias_text", home);
- X sprintf(dest, "%s/%s", home, ALIAS_TEXT);
- X link(source, dest);
- X
- X sprintf(source, "%s/.alias_hash", home);
- X sprintf(dest, "%s/%s", home, ALIAS_HASH);
- X link(source, dest);
- X
- X sprintf(source, "%s/.alias_data", home);
- X sprintf(dest, "%s/%s", home, ALIAS_DATA);
- X link(source, dest);
- X
- X printf("\n*** Moved all data files into %s/.elm directory ***\n\n",
- X home);
- X}
- SHAR_EOF
- chmod 0444 utils/newalias.c || echo "restore of utils/newalias.c fails"
- echo "x - extracting utils/newmail.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/newmail.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: newmail.c,v 4.1 90/04/28 22:44:48 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: newmail.c,v $
- X * Revision 4.1 90/04/28 22:44:48 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This is actually two programs folded into one - 'newmail()' and
- X 'wnewmail()'. They perform essentially the same function, to
- X monitor the mail arriving in a set of/a mailbox or folder, but
- X newmail is designed to run in background on a terminal, and
- X wnewmail is designed to have a window of its own to run in.
- X
- X The main difference is that wnewmail checks for mail more often.
- X
- X The usage parameters are:
- X
- X -i <interval> how often to check for mail
- X (default: 60 secs if newmail,
- X 10 secs if wnewmail)
- X
- X <filename> name of a folder to monitor
- X (can prefix with '+'/'=', or can
- X default to the incoming mailbox)
- X
- X <filename>=prefix file to monitor, output with specified
- X prefix when mail arrives.
- X
- X If we're monitoring more than one mailbox the program will prefix
- X each line output (if 'newmail') or each cluster of mail (if 'wnewmail')
- X with the basename of the folder the mail has arrived in. In the
- X interest of exhaustive functionality, you can also use the "=prefix"
- X suffix (eh?) to specify your own strings to prefix messages with.
- X
- X The output format is either:
- X
- X newmail:
- X >> New mail from <user> - <subject>
- X >> Priority mail from <user> - <subject>
- X
- X >> <folder>: from <user> - <subject>
- X >> <folder>: Priority from <user> - <subject>
- X
- X wnewmail:
- X <user> - <subject>
- X Priority: <user> - <subject>
- X
- X <folder>: <user> - <subject>
- X <folder>: Priority: <user> - <subject>\fR
- X
- X**/
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include "defs.h"
- X
- X#include <signal.h> /* background jobs ignore some signals... */
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#define LINEFEED (char) 10
- X#define BEGINNING 0 /* seek fseek(3S) */
- X#define DEFAULT_INTERVAL 60
- X
- X#define MAX_FOLDERS 25 /* max we can keep track of */
- X
- X#define NO_SUBJECT "(No Subject Specified)"
- X
- X#define metachar(c) (c == '+' || c == '=' || c == '%')
- X
- Xchar *getusername();
- Xlong bytes();
- X
- Xstruct folder_struct {
- X char foldername[SLEN];
- X char prefix[NLEN];
- X FILE *fd;
- X long filesize;
- X } folders[MAX_FOLDERS];
- X
- Xint interval_time, /* how long to sleep between checks */
- X debug = 0, /* include verbose debug output? */
- X in_window = 0, /* are we running as 'wnewmail'? */
- X total_folders = 0, /* # of folders we're monitoring */
- X current_folder = 0; /* struct pointer for looping */
- X
- X#ifdef PIDCHECK
- Xint parent_pid; /* See if sucide should be attempt */
- X#endif /* PIDCHECK */
- X
- Xchar hostname[SLEN], /* name of machine we're on */
- X hostdomain[SLEN]; /* name of domain we're in */
- X
- X#ifdef BSD
- Xextern int errno;
- X#endif
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern char *optarg;
- X extern int optind, opterr;
- X char *ptr;
- X int c, i, done;
- X long lastsize,
- X newsize; /* file size for comparison.. */
- X
- X#ifdef HOSTCOMPILED
- X strncpy(hostname, HOSTNAME, sizeof(hostname));
- X#else
- X gethostname(hostname, sizeof(hostname));
- X#endif
- X gethostdomain(hostdomain, sizeof(hostdomain));
- X
- X#ifdef PIDCHECK /* This will get the pid that */
- X parent_pid = getppid(); /* started the program, ie: /bin/sh */
- X /* If it dies for some reason (logout)*/
- X#endif /* PIDCHECK */ /* Then exit the program if PIDCHECK */
- X
- X interval_time = DEFAULT_INTERVAL;
- X opterr = 0;
- X
- X /** let's see if the first character of the basename of the
- X command invoked is a 'w' (e.g. have we been called as
- X 'wnewmail' rather than just 'newmail'?)
- X **/
- X
- X for (i=0, ptr=(argv[0] + strlen(argv[0])-1); !i && ptr > argv[0]; ptr--)
- X if (*ptr == '/') {
- X in_window = (*(ptr+1) == 'w');
- X i++;
- X }
- X
- X if (ptr == argv[0] && i == 0 && argv[0][0] == 'w')
- X in_window = 1;
- X
- X while ((c = getopt(argc, argv, "di:w")) != EOF) {
- X switch (c) {
- X case 'd' : debug++; break;
- X case 'i' : interval_time = atoi(optarg); break;
- X case 'w' : in_window = 1; break;
- X default : usage(argv[0]); exit(1);
- X }
- X }
- X
- X if (interval_time < 10)
- X fprintf(stderr,
- X"Warning: interval set to %d second%s. I hope you know what you're doing!\n",
- X interval_time, interval_time == 1 ? "" : "s");
- X
- X /* now let's parse the foldernames, if any are given */
- X
- X if (optind >= argc) /* get default */
- X add_default_folder();
- X else {
- X while (optind < argc)
- X add_folder(argv[optind++]);
- X pad_prefixes(); /* for nice output...*/
- X }
- X
- X#ifdef AUTO_BACKGROUND
- X if (! in_window) {
- X if (fork()) /* automatically puts this task in background! */
- X exit(0);
- X
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGQUIT, SIG_IGN);
- X }
- X#endif
- X (void) signal(SIGHUP, SIG_DFL);
- X
- X if (in_window && ! debug)
- X printf("Incoming mail:\n");
- X
- X while (1) {
- X
- X#ifdef PIDCHECK
- X if ( kill(parent_pid,0))
- X exit(0);
- X#else
- X#ifndef AUTO_BACKGROUND /* won't work if we're nested this deep! */
- X if (getppid() == 1) /* we've lost our shell! */
- X exit();
- X#endif /* AUTO_BACKGROUND */
- X#endif /* PIDCHECK */
- X
- X if (! isatty(1)) /* we're not sending output to a tty any more */
- X exit();
- X
- X if (debug) printf("\n----\n");
- X
- X for (i = 0; i < total_folders; i++) {
- X
- X if (debug)
- X printf("[checking folder #%d: %s]\n", i, folders[i].foldername);
- X
- X if (folders[i].fd == (FILE *) NULL) {
- X
- X if ((folders[i].fd = fopen(folders[i].foldername,"r")) == NULL)
- X if (errno == EACCES) {
- X fprintf(stderr, "\nPermission to monitor %s denied!\n\n",
- X folders[i].foldername);
- X sleep(5);
- X exit(1);
- X }
- X }
- X
- X if ((newsize = bytes(folders[i].foldername)) >
- X folders[i].filesize) { /* new mail has arrived! */
- X
- X if (debug)
- X printf(
- X "\tnew mail has arrived! old size = %ld, new size=%ld\n",
- X folders[i].filesize, newsize);
- X
- X /* skip what we've read already... */
- X
- X if (fseek(folders[i].fd, folders[i].filesize,
- X BEGINNING) != 0)
- X perror("fseek()");
- X
- X folders[i].filesize = newsize;
- X
- X read_headers(i); /* read and display new mail! */
- X
- X if (! in_window)
- X printf("\n\r");
- X }
- X else if (newsize != folders[i].filesize) { /* file SHRUNK! */
- X
- X folders[i].filesize = bytes(folders[i].foldername);
- X (void) fclose(folders[i].fd); /* close it and ... */
- X folders[i].fd = (FILE *) NULL; /* let's reopen the file */
- X
- X lastsize = folders[i].filesize;
- X done = 0;
- X
- X while (! done) {
- X sleep(0); /* basically gives up our CPU slice */
- X newsize = bytes(folders[i].foldername);
- X if (newsize != lastsize)
- X lastsize = newsize;
- X else
- X done++;
- X }
- X
- X folders[i].filesize = newsize;
- X }
- X }
- X
- X sleep(interval_time);
- X }
- X}
- X
- Xint
- Xread_headers(current_folder)
- Xint current_folder;
- X{
- X /** read the headers, output as found given current_folder,
- X the prefix of that folder, and whether we're in a window
- X or not.
- X **/
- X
- X char buffer[SLEN], from_whom[SLEN], subject[SLEN];
- X register int subj = 0, in_header = 0, count = 0, priority=0;
- X#ifdef MMDF
- X int newheader = 0;
- X#endif /* MMDF */
- X
- X from_whom[0] = '\0';
- X
- X while (fgets(buffer, SLEN, folders[current_folder].fd) != NULL) {
- X#ifdef MMDF
- X if (strcmp(buffer, MSG_SEPERATOR) == 0) {
- X newheader = !newheader;
- X if (newheader) {
- X#else
- X if (first_word(buffer,"From ")) {
- X if (real_from(buffer, from_whom)) {
- X#endif /* MMDF */
- X subj = 0;
- X priority = 0;
- X in_header = 1;
- X subject[0] ='\0';
- X if (in_window)
- X putchar((char) 007); /* BEEP!*/
- X else
- X printf("\n\r"); /* blank lines surrounding message */
- X
- X }
- X }
- X else if (in_header) {
- X#ifdef MMDF
- X if (first_word(buffer,"From "))
- X real_from(buffer, from_whom);
- X#endif /* MMDF */
- X if (first_word(buffer,">From"))
- X forwarded(buffer, from_whom); /* return address */
- X else if (first_word(buffer,"Subject:") ||
- X first_word(buffer,"Re:")) {
- X if (! subj++) {
- X remove_first_word(buffer);
- X strcpy(subject, buffer);
- X }
- X }
- X else if (first_word(buffer,"Priority:"))
- X priority++;
- X else if (first_word(buffer,"From:"))
- X parse_arpa_from(buffer, from_whom);
- X else if (buffer[0] == LINEFEED) {
- X in_header = 0; /* in body of message! */
- X#ifdef MMDF
- X if (*from_whom == '\0')
- X strcpy(from_whom,getusername());
- X#endif /* MMDF */
- X show_header(priority, from_whom, subject, current_folder);
- X count++;
- X from_whom[0] = '\0';
- X }
- X }
- X }
- X return(count);
- X}
- X
- Xadd_folder(name)
- Xchar *name;
- X{
- X /* add the specified folder to the list of folders...ignore any
- X problems we may having finding it (user could be monitoring
- X a mailbox that doesn't currently exist, for example)
- X */
- X
- X char *cp, buf[SLEN];
- X
- X if (current_folder > MAX_FOLDERS) {
- X fprintf(stderr,
- X "Sorry, but I can only keep track of %d folders.\n", MAX_FOLDERS);
- X exit(1);
- X }
- X
- X /* now let's rip off the suffix "=<string>" if it's there... */
- X
- X for (cp = name + strlen(name); cp > name+1 && *cp != '=' ; cp--)
- X /* just keep stepping backwards */ ;
- X
- X /* if *cp isn't pointing to the first character we'e got something! */
- X
- X if (cp > name+1) {
- X
- X *cp++ = '\0'; /* null terminate the filename & get prefix */
- X
- X if (metachar(*cp)) cp++;
- X
- X strcpy(folders[current_folder].prefix, cp);
- X }
- X else { /* nope, let's get the basename of the file */
- X for (cp = name + strlen(name); cp > name && *cp != '/'; cp--)
- X /* backing up a bit... */ ;
- X
- X if (metachar(*cp)) cp++;
- X if (*cp == '/') cp++;
- X
- X strcpy(folders[current_folder].prefix, cp);
- X }
- X
- X /* and next let's see what kind of weird prefix chars this user
- X might be testing us with. We can have '+'|'='|'%' to expand
- X or a file located in the incoming mail dir...
- X */
- X
- X if (metachar(name[0]))
- X expand_filename(name, folders[current_folder].foldername);
- X else if (access(name, 00) == -1) {
- X /* let's try it in the mail home directory */
- X sprintf(buf, "%s%s", mailhome, name);
- X if (access(buf, 00) != -1) /* aha! */
- X strcpy(folders[current_folder].foldername, buf);
- X else
- X strcpy(folders[current_folder].foldername, name);
- X }
- X else
- X strcpy(folders[current_folder].foldername, name);
- X
- X /* now let's try to actually open the file descriptor and grab
- X a size... */
- X
- X if ((folders[current_folder].fd =
- X fopen(folders[current_folder].foldername, "r")) == NULL)
- X if (errno == EACCES) {
- X fprintf(stderr, "\nPermission to monitor \"%s\" denied!\n\n",
- X folders[current_folder].foldername);
- X exit(1);
- X }
- X
- X folders[current_folder].filesize =
- X bytes(folders[current_folder].foldername);
- X
- X /* and finally let's output what we did */
- X
- X if (debug)
- X printf("folder %d: \"%s\" <%s> %s, size = %ld\n",
- X current_folder,
- X folders[current_folder].foldername,
- X folders[current_folder].prefix,
- X folders[current_folder].fd == NULL? "not found" : "opened",
- X folders[current_folder].filesize);
- X
- X /* and increment current-folder please! */
- X
- X current_folder++;
- X total_folders++;
- X}
- X
- Xadd_default_folder()
- X{
- X char *cp;
- X
- X /* this routine will add the users home mailbox as the folder
- X * to monitor. Since there'll only be one folder we'll never
- X * prefix it either...
- X * determine mail file from environment variable if found,
- X * else use password entry
- X */
- X if ((cp = getenv("MAIL")) == NULL)
- X sprintf(folders[0].foldername, "%s%s", mailhome, getusername());
- X else
- X strcpy(folders[0].foldername, cp);
- X
- X folders[0].fd = fopen(folders[0].foldername, "r");
- X folders[0].filesize = bytes(folders[0].foldername);
- X
- X if (debug)
- X printf("default folder: \"%s\" <%s> %s, size = %ld\n",
- X folders[0].foldername,
- X folders[0].prefix,
- X folders[0].fd == NULL? "not found" : "opened",
- X folders[0].filesize);
- X
- X total_folders = 1;
- X}
- X
- Xint
- Xreal_from(buffer, who)
- Xchar *buffer, *who;
- X{
- X /***** returns true iff 's' has the seven 'from' fields,
- X initializing the who to the sender *****/
- X
- X char junk[SLEN], who_tmp[SLEN];
- X
- X junk[0] = '\0';
- X who_tmp[0] = '\0';
- X
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
- X who, junk);
- X
- X if (junk[0] != '\0')
- X strcpy(who, who_tmp);
- X
- X return(junk[0] != '\0');
- X}
- X
- Xforwarded(buffer, who)
- Xchar *buffer, *who;
- X{
- X /** change 'from' and date fields to reflect the ORIGINATOR of
- X the message by iteratively parsing the >From fields... **/
- X
- X char machine[SLEN], buff[SLEN];
- X
- X machine[0] = '\0';
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %s",
- X who, machine);
- X
- X if(machine[0] == '\0') /* try for address with timezone in date */
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
- X who, machine);
- X
- X if (machine[0] == '\0') /* try for srm address */
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
- X who, machine);
- X
- X if (machine[0] == '\0')
- X sprintf(buff,"anonymous");
- X else
- X sprintf(buff,"%s!%s", machine, who);
- X
- X strncpy(who, buff, SLEN);
- X}
- 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
- 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
- Xshow_header(priority, from, subject, current_folder)
- Xint priority;
- Xchar *from, *subject;
- Xint current_folder;
- X{
- X /** output header in clean format, including abbreviation
- X of return address if more than one machine name is
- X contained within it! **/
- X char buffer[SLEN];
- X int loc, i=0, exc=0, len;
- X
- X#ifndef INTERNET
- X /* Remove bogus "@host.domain" string. */
- X
- X sprintf(buffer, "@%s%s", hostname, hostdomain);
- X
- X if (chloc(from, '!') != -1 && in_string(from, buffer))
- X from[strlen(from) - strlen(buffer)] = '\0';
- X#endif
- X
- X loc = strlen(from);
- X
- X while (exc < 2 && loc > 0)
- X if (from[--loc] == '!')
- X exc++;
- X
- X if (exc == 2) { /* lots of machine names! Get last one */
- X loc++;
- X len = strlen(from);
- X while (loc < len && loc < SLEN)
- X buffer[i++] = from[loc++];
- X buffer[i] = '\0';
- X strcpy(from, buffer);
- X }
- X
- X if (strlen(subject) < 2)
- X strcpy(subject, NO_SUBJECT);
- X
- X if (in_window)
- X if (total_folders > 1)
- X printf("%s: %s%s -- %s\n",
- X folders[current_folder].prefix,
- X priority? "Priority " : "", from, subject);
- X else
- X printf("%s%s -- %s\n",
- X priority? "Priority " : "", from, subject);
- X else
- X if (total_folders > 1)
- X printf(">> %s: %sail from %s - %s\n\r",
- X folders[current_folder].prefix,
- X priority? "Priority m" : "M", from, subject);
- X else
- X printf(">> %sail from %s - %s\n\r",
- X priority? "Priority m" : "M", from, subject);
- X}
- X
- Xparse_arpa_from(buffer, newfrom)
- Xchar *buffer, *newfrom;
- X{
- X /** try to parse the 'From:' line given... It can be in one of
- X three formats:
- X From: Dave Taylor <hpcnou!dat>
- X or From: hpcnou!dat (Dave Taylor)
- X or From: hpcnou!dat
- X Change 'newfrom' ONLY if sucessfully parsed this entry and
- X the resulting name is non-null!
- X **/
- X
- X char temp_buffer[SLEN], *temp;
- X register int i, j = 0, in_parens;
- X
- X temp = (char *) temp_buffer;
- X temp[0] = '\0';
- X
- X no_ret(buffer); /* blow away '\n' char! */
- X
- X if (lastch(buffer) == '>') {
- X for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- X buffer[i] != '('; i++)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X }
- X else if (lastch(buffer) == ')') {
- X in_parens = 1;
- X for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '<'; i--) {
- X switch(buffer[i]) {
- X case ')': in_parens++;
- X break;
- X case '(': in_parens--;
- X break;
- X }
- X if(!in_parens) break;
- X temp[j++] = buffer[i];
- X }
- X temp[j] = '\0';
- X reverse(temp);
- X }
- X else
- X /* Unusual to have address like - From: hpcnou!dat
- X * but valid */
- X {
- X for (i=strlen("From: "); buffer[i] != '\0'; i++)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X }
- X
- X if (strlen(temp) > 0) { /* mess with buffer... */
- X
- X /* remove leading spaces... */
- X
- X while (whitespace(temp[0]))
- X temp = (char *) (temp + 1); /* increment address! */
- X
- X /* remove trailing spaces... */
- X
- X i = strlen(temp) - 1;
- X
- X while (whitespace(temp[i]))
- X temp[i--] = '\0';
- X
- X /* if anything is left, let's change 'from' value! */
- X
- X if (strlen(temp) > 0)
- X strcpy(newfrom, temp);
- X }
- 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
- Xlong
- Xbytes(name)
- Xchar *name;
- X{
- X /** return the number of bytes in the specified file. This
- X is to check to see if new mail has arrived.... **/
- X
- X int ok = 1;
- X extern int errno; /* system error number! */
- X struct stat buffer;
- X
- X if (stat(name, &buffer) != 0)
- X if (errno != 2) {
- X fprintf(stderr,"Error %d attempting fstat on %s", errno, name);
- X exit(1);
- X }
- X else
- X ok = 0;
- X
- X return(ok ? buffer.st_size : 0);
- X}
- X
- Xchar *getusername()
- X{
- X /** Getting the username on some systems is a real pain, so...
- X This routine is guaranteed to return a usable username **/
- X
- X char *return_value, *getlogin(), *cuserid();
- X
- X if ((return_value = getlogin()) == NULL)
- X if ((return_value = cuserid(NULL)) == NULL) {
- X printf("Newmail: I can't get username!\n");
- X exit(1);
- X }
- X
- X return( (char *) return_value);
- X}
- X
- Xusage(name)
- Xchar *name;
- X{
- X /* print a nice friendly usage message */
- X
- X fprintf(stderr,
- X"\nUsage: %s [-d] [-i interval] [-w] {folders}\n", name);
- X fprintf(stderr, "\nWhere:\n");
- X fprintf(stderr, " -d\tturns on debugging output\n");
- X fprintf(stderr,
- X" -i D\tsets the interval checking time to 'D' seconds\n");
- X fprintf(stderr,
- X" -w\tforces 'window'-style output, and bypasses auto-background\n\n");
- X fprintf(stderr,
- X"folders can be specified by relative or absolute path names, can be the name\n");
- X fprintf(stderr,
- X"of a mailbox in the incoming mail directory to check, or can have one of the\n");
- X fprintf(stderr,
- X"standard Elm mail directory prefix chars (e.g. '+', '=' or '%').\n");
- X fprintf(stderr,
- X"Furthermore, any folder can have '=string' as a suffix to indicate a folder\n");
- X fprintf(stderr,
- X"identifier other than the basename of the file\n\n");
- X}
- X
- X
- Xexpand_filename(name, store_space)
- Xchar *name, *store_space;
- X{
- X strcpy(store_space, name);
- X if (expand(store_space) == 0) {
- X fprintf(stderr,"Sorry, but I couldn't expand \"%s\"\n",name);
- X exit(1);
- X }
- X}
- X
- Xpad_prefixes()
- X{
- X /** This simple routine is to ensure that we have a nice
- X output format. What it does is whip through the different
- X prefix strings we've been given, figures out the maximum
- X length, then space pads the other prefixes to match.
- X **/
- X
- X register int i, j, len = 0;
- X
- X for (i=0; i < total_folders; i++)
- X if (len < (j=strlen(folders[i].prefix)))
- X len = j;
- X
- X for (i=0; i < total_folders; i++)
- X for (j = strlen(folders[i].prefix); j < len; j++)
- X strcat(folders[i].prefix, " ");
- X}
- SHAR_EOF
- chmod 0444 utils/newmail.c || echo "restore of utils/newmail.c fails"
- echo "x - extracting utils/printmail (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/printmail &&
- X: Use /bin/sh
- X# printmail: part of the Elm mail system
- X# @(#)$Id: printmail,v 4.1 90/04/28 22:44:50 syd Exp $
- X
- Xif [ "$1" = "-p" ]; then
- X flags="-p";shift
- Xfi
- X
- Xif [ "$1" != "" ]; then
- X if [ ! -r $1 ]; then
- X echo printmail: cannot open folder $1 1>&2
- X exit 1
- X else
- X flags="$flags -f $1"
- X fi
- Xfi
- X
- X# and now invoke readmsg
- Xexec readmsg $flags \*
- SHAR_EOF
- chmod 0444 utils/printmail || echo "restore of utils/printmail fails"
- echo "x - extracting utils/readmsg.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > utils/readmsg.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: readmsg.c,v 4.1 90/04/28 22:44:52 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: readmsg.c,v $
- X * Revision 4.1 90/04/28 22:44:52 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This routine adds the functionality of the "~r" command to the Elm mail
- X system while still allowing the user to use the editor of their choice.
- X
- X The program, without any arguments, tries to read a file in the users home
- X directory called ".readmsg" (actually defined in the sysdefs.h system
- X defines file) and if it finds it reads the current message. If it doesn't
- X find it, it will return a usage error.
- X
- X The program can also be called with an explicit message number, list of
- X message numbers, or a string to match in the message (including the header).
- X NOTE that when you use the string matching option it will match the first
- X message containing that EXACT (case sensitive) string and then exit.
- X**/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "defs.h"
- X
- X/** three defines for what level of headers to display **/
- X
- X#define ALL 1
- X#define WEED 2
- X#define NONE 3
- X
- X#define metachar(c) (c == '=' || c == '+' || c == '%')
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#define MAX_LIST 25 /* largest single list of arguments */
- X
- X#define LAST_MESSAGE 9999 /* last message in list ('$' char) */
- X#define LAST_CHAR '$' /* char to delimit last message.. */
- X#define STAR '*' /* char to delimit all messages... */
- X
- Xint read_message[MAX_LIST]; /* list of messages to read */
- Xint messages = 0; /* index into list of messages */
- X
- Xint numcmp(); /* strcmp, but for numbers */
- Xchar *words(); /* function defined below... */
- X
- X
- Xextern char *optarg; /* for parsing the ... */
- Xextern int optind; /* .. starting arguments */
- X
- Xchar *getenv(); /* keep lint happy */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *file; /* generic file descriptor! */
- X char filename[SLEN], /* filename buffer */
- X infile[SLEN], /* input filename */
- X buffer[SLEN], /* file reading buffer */
- X string[SLEN], /* string match buffer */
- X *cp;
- X
- X int current_in_queue = 0, /* these are used for... */
- X current = 0, /* ...going through msgs */
- X list_all_messages = 0, /* just list 'em all?? */
- X num, /* for argument parsing */
- X page_breaks = 0, /* use "^L" breaks?? */
- X total, /* number of msgs current */
- X include_headers = WEED, /* flag: include msg header? */
- X last_message = 0, /* flag: read last message? */
- X not_in_header = 0, /* flag: in msg header? */
- X#ifdef MMDF
- X newheader = 0, /* flag: hit ^A^A^A^A line */
- X#endif /* MMDF */
- X string_match = 0; /* flag: using string match? */
- X string[0] = '\0'; /* init match string to empty */
- X
- X /**** start of the actual program ****/
- X
- X while ((num = getopt(argc, argv, "nhf:p")) != EOF) {
- X switch (num) {
- X case 'n' : include_headers = NONE; break;
- X case 'h' : include_headers = ALL; break;
- X case 'f' : strcpy(infile, optarg);
- X if (metachar(infile[0]))
- X if (expand(infile) == 0)
- X printf("%s: couldn't expand filename %s!\n",
- X argv[0], infile);
- X break;
- X case 'p' : page_breaks++; break;
- X case '?' : printf(
- X "Usage: %s [-n|-h] [-f filename] [-p] <message list>\n",
- X argv[0]);
- X exit(1);
- X }
- X }
- X
- X /** whip past the starting arguments so that we're pointing
- X to the right stuff... **/
- X
- X *argv++; /* past the program name... */
- X
- X while (optind-- > 1) {
- X *argv++;
- X argc--;
- X }
- X
- X /** now let's figure out the parameters to the program... **/
- X
- X if (argc == 1) { /* no arguments... called from 'Elm'? */
- X sprintf(filename, "%s/%s", getenv("HOME"), readmsg_file);
- X if ((file = fopen(filename, "r")) != NULL) {
- X fscanf(file, "%d", &(read_message[messages++]));
- X fclose(file);
- X }
- X else { /* no arguments AND no .readmsg file!! */
- X fprintf(stderr,
- X "Usage: readmsg [-n|-h] [-f filename] [-p] <message list>\n");
- X exit(1);
- X }
- X }
- X else if (! isdigit(*argv[0]) && *argv[0] != LAST_CHAR &&
- X *argv[0] != STAR) {
- X string_match++;
- X
- X while (*argv)
- X sprintf(string, "%s%s%s", string, string[0] == '\0'? "" : " ",
- X *argv++);
- X }
- X else if (*argv[0] == STAR) /* all messages.... */
- X list_all_messages++;
- X else { /* list of nums */
- X
- X while (--argc > 0) {
- X num = -1;
- X
- X sscanf(*argv,"%d", &num);
- X
- X if (num < 0) {
- X if (*argv[0] == LAST_CHAR) {
- X last_message++;
- X num = LAST_MESSAGE;
- X }
- X else {
- X fprintf(stderr,"I don't understand what '%s' means...\n",
- X *argv);
- X exit(1);
- X }
- X }
- X else if (num == 0) { /* another way to say "last" */
- SHAR_EOF
- echo "End of part 25"
- echo "File utils/readmsg.c is continued in part 26"
- echo "26" > s2_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-