home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i033: Elm mail system (elm), Part08/14
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
- Mod.sources: Volume 6, Issue 33
- Archive-name: elm/Part08
-
- # Continuation of Shell Archive, created by hpldat!taylor
-
- # This is part 8
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/utils.c ----------
-
- filename="src/utils.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/utils.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** utils.c **/
-
- /** Utility routines for ELM
-
- All routines herein: (C) Copyright 1985 Dave Taylor
- **/
-
- #include "headers.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- #include <signal.h>
-
- emergency_exit()
- {
- /** used in dramatic cases when we must leave without altering
- ANYTHING about the system... **/
-
- dprint0(1,
- "\nERROR: Something dreadful is happening! Taking emergency exit!!\n\n");
- dprint0(1," possibly leaving behind the following files;\n");
- dprint2(1," The mailbox tempfile : %s%s\n", temp_mbox, username);
- dprint2(1," The mailbox lock file: %s%s.lock\n", mailhome, username);
- dprint2(1," The composition file : %s%d\n", temp_file, getpid());
- dprint2(1," The header comp file : %s%d\n", temp_file, getpid()+1);
- dprint2(1," The readmsg data file: %s/%s\n", home, readmsg_file);
-
- Raw(OFF);
- if (cursor_control) transmit_functions(OFF);
- if (hp_terminal) softkeys_off();
-
- if (cursor_control)
- MoveCursor(LINES, 0);
-
- PutLine0(LINES,0, "\nEmergency Exit taken! All temp files intact!\n\n");
-
- exit(1);
- }
-
- leave(val)
- int val; /* not used, placeholder for signal catching! */
- {
- char buffer[SLEN];
-
- dprint0(2,"\nLeaving mailer normally (leave)\n");
-
- Raw(OFF);
- if (cursor_control) transmit_functions(OFF);
- if (hp_terminal) softkeys_off();
-
- sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s%d",temp_file, getpid()+1); /* editor buffer */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s%s",temp_mbox, username); /* temp mailbox */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s/%s", home, readmsg_file); /* readmsg temp */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s%s.lock",mailhome, username); /* lock file */
- (void) unlink(buffer);
-
- if (! mail_only) {
- MoveCursor(LINES,0);
- Writechar('\n');
- }
-
- exit(0);
- }
-
- leave_locked(val)
- int val; /* not used, placeholder for signal catching! */
- {
- /** same as leave routine, but don't disturb lock file **/
-
- char buffer[SLEN];
-
- dprint0(3,
- "\nLeaving mailer due to presence of lock file (leave_locked)\n");
-
- Raw(OFF);
- if (cursor_control) transmit_functions(OFF);
- if (hp_terminal) softkeys_off();
-
- sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s%d",temp_file, getpid()+1); /* editor buffer */
- (void) unlink(buffer);
-
- sprintf(buffer,"%s%s",temp_mbox, username); /* temp mailbox */
- (void) unlink(buffer);
-
- MoveCursor(LINES,0);
- Writechar('\n');
-
- exit(0);
- }
-
- int
- get_page(msg_pointer)
- int msg_pointer;
- {
- /** ensure that 'current' is on the displayed page,
- returning non-zero iff the page changed! **/
-
- register int first_on_page, last_on_page;
-
- first_on_page = (header_page * headers_per_page) + 1;
-
- last_on_page = first_on_page + headers_per_page - 1;
-
- if (msg_pointer > last_on_page) {
- header_page = (int) (msg_pointer-1) / headers_per_page;
- return(1);
- }
- else if (msg_pointer < first_on_page) {
- header_page = (int) (msg_pointer-1) / headers_per_page;
- return(1);
- }
- else
- return(0);
- }
-
- int
- copy_to_self(buffer)
- char *buffer;
- {
- /** returns true iff buffer = 'Cc: username' where username
- is the account name of the person sending the message.
- Used for weeding out 'Cc:' lines from the messages if
- 'weed' is turned on. **/
-
- /** note: tail_of() is located in file "strings.c" **/
-
- char name[SLEN], buf[SLEN];
- register int i=0, j=0;
-
- tail_of(header_table[current-1].from, name, FALSE);
-
- while (name[i] != '!' && i < strlen(name))
- i++;
-
- if (name[i] == '!') {
- for (i++; i < strlen(name); i++)
- name[j++] = name[i];
-
- name[j] = 0;
- }
-
- sprintf(buf, "Cc: %s\n", name);
-
- return( strcmp(buf, buffer) == 0 );
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 3786 ]
- then
- echo $filename changed - should be 3786 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/validname.c ----------
-
- filename="src/validname.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/validname.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** validname.c **/
-
- /** This routine takes a single address, no machine hops or
- anything, and returns 1 if it's valid and 0 if not. The
- algorithm it uses is the same one that uux uses, namely:
-
- 1. Is there a file '/usr/mail/%s'?
- 2. Is there a password entry for %s?
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include <stdio.h>
-
- #include "defs.h"
-
- int
- valid_name(name)
- char *name;
- {
- /** does what it says above, boss! **/
-
- #ifdef NOCHECK_VALIDNAME
-
- return(1); /* always say it's okay! */
-
- #else
- char filebuf[SLEN];
-
- sprintf(filebuf,"%s/%s", mailhome, name);
-
- if (access(filebuf, ACCESS_EXISTS) == 0)
- return(1);
-
- if (getpwnam(name) != NULL)
- return(1);
-
- return(0);
-
- #endif
-
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 706 ]
- then
- echo $filename changed - should be 706 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/syscall.c ----------
-
- filename="src/syscall.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/syscall.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** syscall.c **/
-
- /** These routines are used for user-level system calls, including the
- '!' command and the '|' commands...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <signal.h>
-
- char *argv_zero();
-
- int
- subshell()
- {
- /** spawn a subshell with either the specified command
- returns non-zero if screen rewrite needed
- **/
-
- char command[SLEN];
- int ret;
-
- PutLine0(LINES-3,COLUMNS-40,"(use the shell name for a shell)");
- PutLine0(LINES-2,0,"Shell Command: ");
- command[0] = '\0';
- (void) optionally_enter(command, LINES-2, 15, FALSE);
- if (strlen(command) == 0) {
- MoveCursor(LINES-2,0); CleartoEOLN();
- return(0);
- }
-
- MoveCursor(LINES,0); CleartoEOLN();
- Raw(OFF);
- if (cursor_control) transmit_functions(OFF);
-
- ret = system_call(command, USER_SHELL);
-
- PutLine0(LINES, 0, "\n\nPress <return> to return to ELM: ");
-
- Raw(ON);
- (void) getchar();
- if (cursor_control) transmit_functions(ON);
-
- if (ret != 0) error1("Return code was %d", ret);
- return(1);
- }
-
- system_call(string, shell_type)
- char *string;
- int shell_type;
- {
- /** execute 'string', setting uid to userid... **/
- /** if shell-type is "SH" /bin/sh is used regardless of the
- users shell setting. Otherwise, "USER_SHELL" is sent **/
-
- int status, pid, w;
- register int (*istat)(), (*qstat)();
-
- dprint2(2,"System Call: %s\n\t%s\n", shell_type == SH? "/bin/sh" : shell,
- string);
-
- #ifdef NO_VM /* machine without virtual memory! */
- if ((pid = fork()) == 0) {
- #else
- if ((pid = vfork()) == 0) {
- #endif
- setuid(userid); /* back to the normal user! */
- setgid(groupid); /* and group id */
-
- if (strlen(shell) > 0 && shell_type == USER_SHELL) {
- execl(shell, argv_zero(shell), "-c", string, 0);
- }
- else
- execl("/bin/sh", "sh", "-c", string, 0);
- _exit(127);
- }
-
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
-
- while ((w = wait(&status)) != pid && w != -1)
- ;
-
- if (w == -1) status = -1;
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
-
- return(status);
- }
-
- int
- do_pipe()
- {
- /** pipe the tagged messages to the specified sequence.. **/
-
- char command[SLEN], buffer[LONG_SLEN], message_list[SLEN];
- register int ret, tagged = 0, oldstat, i;
-
- message_list[0] = '\0'; /* NULL string to start... */
-
- for (i=0; i < message_count; i++)
- if (ison(header_table[i].status, TAGGED)) {
- sprintf(message_list,"%s %d", message_list,
- header_table[i].index_number);
- tagged++;
- }
-
- if (tagged > 1)
- PutLine0(LINES-2,0,"Pipe tagged msgs to: ");
- else if (tagged)
- PutLine0(LINES-2,0,"Pipe tagged msg to : ");
- else {
- PutLine0(LINES-2,0,"Pipe current msg to: ");
- sprintf(message_list,"%d", header_table[current-1].index_number);
- }
-
- command[0] = '\0';
-
- (void) optionally_enter(command, LINES-2, 21, FALSE);
- if (strlen(command) == 0) {
- MoveCursor(LINES-2,0); CleartoEOLN();
- return(0);
- }
-
- MoveCursor(LINES,0); CleartoEOLN();
- Raw(OFF);
-
- if (cursor_control) transmit_functions(OFF);
-
- sprintf(buffer, "%s -f %s -h %s | %s",
- readmsg,
- infile,
- message_list,
- command);
-
- ret = system_call(buffer, USER_SHELL);
-
- PutLine0(LINES, 0, "\n\nPress <return> to return to ELM: ");
- Raw(ON);
- (void) getchar();
- if (cursor_control) transmit_functions(ON);
-
- if (ret != 0) error1("Return code was %d", ret);
- return(1);
- }
-
- printmsg()
- {
- /** Print current message or tagged messages using 'printout'
- variable. Error message iff printout not defined! **/
-
- char buffer[LONG_SLEN], filename[SLEN], printbuffer[LONG_SLEN];
- char message_list[SLEN];
- register int retcode, tagged = 0, oldstat, i;
-
- if (strlen(printout) == 0) {
- error("Don't know how to print - option \"printmail\" undefined!");
- return;
- }
-
- message_list[0] = '\0'; /* reset to null... */
-
- for (i=0; i < message_count; i++)
- if (header_table[i].status & TAGGED) {
- sprintf(message_list, "%s %d", message_list,
- header_table[i].index_number);
- tagged++;
- }
-
- if (! tagged)
- sprintf(message_list," %d", header_table[current-1].index_number);
-
- sprintf(filename,"%s%d", temp_print, getpid());
-
- if (in_string(printout, "%s"))
- sprintf(printbuffer, printout, filename);
- else
- sprintf(printbuffer, "%s %s", printout, filename);
-
- sprintf(buffer,"(%s -p -f %s%s > %s; %s 2>&1) > /dev/null",
- readmsg, infile, message_list,
- filename,
- printbuffer);
-
- dprint0(2,"Printing system call...\n");
-
- Centerline(LINES, "queueing...");
-
- if ((retcode = system_call(buffer, SH)) == 0) {
- sprintf(buffer, "Message%s queued up to print", plural(tagged));
- Centerline(LINES, buffer);
- }
- else
- error1("Printout failed with return code %d", retcode);
-
- unlink(filename); /* remove da temp file! */
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4692 ]
- then
- echo $filename changed - should be 4692 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/aliaslib.c ----------
-
- filename="src/aliaslib.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/aliaslib.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** aliaslib.c **/
-
- /** Library of functions dealing with the alias system...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- char *expand_group(), *get_alias_address(), *expand_system();
- char *get_token(), *strpbrk();
-
- char *get_alias_address(name, mailing, depth)
- char *name;
- int mailing, depth;
- {
- /** return the line from either datafile that corresponds
- to the specified name. If 'mailing' specified, then
- fully expand group names. Depth specifies the nesting
- depth - the routine should always initially be called
- with this equal 0. Returns NULL if not found **/
-
- static char buffer[VERY_LONG_STRING];
- int loc;
-
- if (strlen(name) == 0)
- return( (char *) NULL);
-
- if (user_files)
- if ((loc = find(name, user_hash_table, MAX_UALIASES)) >= 0) {
- lseek(user_data, user_hash_table[loc].byte, 0L);
- get_line(user_data, buffer);
- if (buffer[0] == '!' && mailing)
- return(expand_group(buffer, depth));
- else if (strpbrk(buffer,"!@:") != NULL) /* has a hostname */
- return(expand_system(buffer, TRUE));
- else
- return((char *) buffer);
- }
-
- if (system_files)
- if ((loc = find(name, system_hash_table, MAX_SALIASES)) >= 0) {
- lseek(system_data, system_hash_table[loc].byte, 0L);
- get_line(system_data, buffer);
- if (buffer[0] == '!' && mailing)
- return(expand_group(buffer, depth));
- else if (strpbrk(buffer,"!@:") != NULL) /* has a hostname */
- return(expand_system(buffer, TRUE));
- else
- return((char *) buffer);
- }
-
- return( (char *) NULL);
- }
-
- char *expand_system(buffer, show_errors)
- char *buffer;
- int show_errors;
- {
- /** This routine will check the first machine name in the given path
- (if any) and expand it out if it is an alias...if not, it will
- return what it was given. If show_errors is false, it won't
- display errors encountered...
- **/
-
- dprint2(6, "expand_system(%s, show-errors=%s)\n", buffer,
- onoff(show_errors));
- findnode(buffer, show_errors);
-
- return( (char *) buffer);
- }
-
- char *expand_group(members, depth)
- char *members;
- int depth;
- {
- /** Given a group of names separated by commas, this routine
- will return a string that is the full addresses of each
- member separated by spaces. Depth is an internal counter
- that keeps track of the depth of nesting that the routine
- is in...it's for the get_token routine! **/
-
- static char buffer[VERY_LONG_STRING];
- char buf[LONG_STRING], *word, *address, *bufptr;
-
- strcpy(buf, members); /* parameter safety! */
- if (depth == 0) buffer[0] = '\0'; /* nothing in yet! */
- bufptr = (char *) buf; /* grab the address */
- depth++; /* one deeper! */
-
- while ((word = get_token(bufptr, "!, ", depth)) != NULL) {
- if ((address = get_alias_address(word, 1, depth)) == NULL) {
- if (! valid_name(word)) {
- dprint2(3, "Encountered illegal address %s (%s)\n",
- word, "expand_group");
- error1("%s is an illegal address!", word);
- return( (char *) NULL);
- }
- else if (strcmp(buffer, word) != 0)
- sprintf(buffer, "%s%s%s", buffer,
- (strlen(buffer) > 0)? ", ":"", word);
- }
- else if (strcmp(buffer, address) != 0)
- sprintf(buffer,"%s%s%s", buffer,
- (strlen(buffer) > 0)? ", ":"", address);
-
- bufptr = NULL;
- }
-
- return( (char *) buffer);
- }
-
- int
- find(word, table, size)
- char *word;
- struct alias_rec table[];
- int size;
- {
- /** find word and return loc, or -1 **/
- register int loc;
-
- if (strlen(word) > 20) {
- dprint2(3, "Too long alias name entered [%s] (%s)\n", word, "find");
- error1("Bad alias name: %s. Too long.\n", word);
- return(-1);
- }
-
- loc = hash_it(word, size);
-
- while (strcmp(word, table[loc].name) != 0) {
- if (table[loc].name[0] == '\0')
- return(-1);
- loc = (loc + 1) % size;
- }
-
- return(loc);
- }
-
- int
- hash_it(string, table_size)
- char *string;
- int table_size;
- {
- /** compute the hash function of the string, returning
- it (mod table_size) **/
-
- register int i, sum = 0;
-
- for (i=0; string[i] != '\0'; i++)
- sum += (int) string[i];
-
- return(sum % table_size);
- }
-
- get_line(fd, buffer)
- int fd;
- char *buffer;
- {
- /* read from file fd. End read upon reading either
- EOF or '\n' character (this is where it differs
- from a straight 'read' command!) */
-
- register int i= 0;
- char ch;
-
- while (read(fd, &ch, 1) > 0)
- if (ch == '\n' || ch == '\r') {
- buffer[i] = 0;
- return;
- }
- else
- buffer[i++] = ch;
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4476 ]
- then
- echo $filename changed - should be 4476 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/domains.c ----------
-
- filename="src/domains.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/domains.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** domains.c **/
-
- /** This file contains all the code dealing with the expansion of
- domain based addresses in Elm. It uses the file "domains" as
- defined in the sysdefs.h file.
-
- (C) Copyright 1986 Dave Taylor
-
- From a file format and idea in "uumail" - designed by Stan Barber.
- **/
-
- #include <stdio.h>
- #include <ctype.h>
-
- #include "headers.h"
-
- /** define the various characters that we can encounter after a "%" sign
- in the template file...
- **/
-
- #define USERNAME 'U' /* %U = the name of the remote user */
- #define HOSTNAME 'N' /* %N = the remote machine name */
- #define FULLNAME 'D' /* %D = %N + domain info given */
- #define NPATH 'R' /* %R = path to %N from pathalias */
- #define PPATH 'P' /* %P = path to 'P' from pathalias */
- #define OBSOLETE 'S' /* %S = (used to be suffix string) */
-
- /** and finally some characters that are allowed in user/machine names **/
-
- #define okay_others(c) (c == '-' || c == '^' || c == '$' || c == '_')
-
- /** and some allowed ONLY in the username field **/
-
- #define special_chars(c) (c == '%' || c == ':')
-
- char *find_path_to(), *expand_domain(), *match_and_expand_domain();
-
- open_domain_file()
- {
- if ((domainfd = fopen(domains, "r")) == NULL) {
- dprint1(1, "Can't open file %s as domains file (open_domain_file)\n",
- domains);
- }
- else {
- dprint1(2,
- "\nOpened '%s' as the domain database. (open_domain_file)\n\n",
- domains);
- }
-
- /* if it fails it'll instantiate domainfd to NULL which is
- exactly what we want to have happen!! */
- }
-
- char *expand_domain(buffer)
- char *buffer;
- {
- /** Expand the address 'buffer' based on the domain information,
- if any. Returns NULL if it can't expand it for any reason.
- **/
-
- char name[2*NLEN], address[2*NLEN], domain[2*NLEN];
- char *match_and_expand_domain();
-
- if (domainfd == NULL) return(NULL); /* no file present! */
-
- if (explode(buffer, name, address, domain))
- return( match_and_expand_domain(domain, name, address) );
- else { /* invalid format - not "user@host.domain" */
- dprint1(3,
- "Invalid format for domain expansion: %s (expand_domain)\n",
- buffer);
- return(NULL);
- }
- }
-
- int
- explode(buffer, name, address, domain)
- char *buffer, *name, *address, *domain;
- {
- /** Break buffer, if in format name@machine.domain, into the
- component parts, otherwise return ZERO and don't worry
- about the values of the parameters!
- **/
-
- register int i, j = 0;
-
- /** First get the name... **/
-
- for (i=0; buffer[i] != '@'; i++) {
- if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) && !
- special_chars(buffer[i]))
- return(0); /* invalid character in string! */
- name[i] = buffer[i];
- }
-
- name[i++] = '\0';
-
- /** now let's get the machinename **/
-
- while (buffer[i] != '.') {
- if (! isalnum(buffer[i]) && ! okay_others(buffer[i]))
- return(0); /* invalid character in string! */
- address[j++] = buffer[i++];
- }
- address[j] = '\0';
-
- j = 0;
-
- /** finally let's get the domain information (there better be some!) **/
-
- while (buffer[i] != '\0') {
- if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) &&
- buffer[i] != '.')
- return(0); /* an you fail again, bozo! */
- domain[j++] = toupper(buffer[i]);
- i++;
- }
-
- domain[j] = '\0';
-
- return(j); /* if j == 0 there's no domain info! */
- }
-
- char *match_and_expand_domain(domain, name, machine)
- char *domain, *name, *machine;
- {
- /** Given the domain, try to find it in the domain file and
- if found expand the entry and return the result as a
- character string...
- **/
-
- static char address[SLEN];
- char buffer[SLEN], domainbuff[NLEN];
- char field1[2*NLEN], field2[2*NLEN], field3[2*NLEN];
- char *path, *template, *expanded, *mydomain;
- int matched = 0, in_percent = 0;
- register int i, j = 0;
-
- address[j] = '\0';
-
- domainbuff[0] = '\0';
- mydomain = (char *) domainbuff; /* set up buffer etc */
-
- do {
- rewind(domainfd); /* back to ground zero! */
-
- if (strlen(mydomain) > 0) { /* already in a domain! */
- mydomain++; /* skip leading '.' */
- while (*mydomain != '.' && *mydomain != ',')
- mydomain++; /* next character */
- if (*mydomain == ',')
- return (NULL); /* didn't find domain! */
- }
- else
- sprintf(mydomain, "%s,", domain); /* match ENTIRELY! */
-
- /* whip through file looking for the entry, please... */
-
- while (fgets(buffer, SLEN, domainfd) != NULL) {
- if (buffer[0] == '#') /* skip comments */
- continue;
- if (strncmp(buffer, mydomain, strlen(mydomain)) == 0) { /* match? */
- matched++; /* Gotcha! Remember this momentous event! */
- break;
- }
- }
-
- if (! matched)
- continue; /* Nothing. Not a sausage! Step through! */
-
- /** We've matched the domain! **/
-
- no_ret(buffer);
-
- (void) strtok(buffer, ","); /* skip the domain info */
-
- strcpy(field1, strtok(NULL, ",")); /* fun */
- strcpy(field2, strtok(NULL, ",")); /* stuff */
- strcpy(field3, strtok(NULL, ",")); /* eh? */
-
- path = (char *) NULL;
-
- /* now we merely need to figure out what permutation this is! */
-
- if (field3 == NULL || strlen(field3) == 0)
- if (field2 == NULL || strlen(field2) == 0)
- template = (char *) field1;
- else {
- path = (char *) field1;
- template = (char *) field2;
- }
- else {
- dprint1(2,"Domain info for %s from file broken into THREE fields!!\n",
- domain);
- dprint3(2, "-> %s\n-> %s\n-> %s\n", field1, field2, field3);
- error1("Warning: domain %s uses a defunct field!!", domain);
- sleep(2);
- path = (char *) field1;
- template = (char *) field3;
- }
-
- if (strlen(path) > 0 && path[0] == '>')
- path++; /* skip the '>' character, okay? */
-
- j = 0; /* address is zero, right now, right?? */
- address[j] = '\0'; /* make sure string is too! */
-
- for (i=0; i < strlen(template); i++) {
- if (template[i] == '%') {
- if (! in_percent) /* just hit a NEW percent! */
- in_percent = 1;
- else { /* just another percent sign on the wall... */
- address[j++] = '%';
- address[j] = '\0'; /* ALWAYS NULL terminate */
- in_percent = 0;
- }
- }
- else if (in_percent) { /* Hey! a real command string */
- in_percent = 0;
- switch (template[i]) {
- case USERNAME: strcat(address, name); break;
- case HOSTNAME: strcat(address, machine); break;
- case FULLNAME: strcat(address, machine);
- strcat(address, domain); break;
- case NPATH :
-
- if ((expanded = find_path_to(machine, FALSE)) == NULL) {
- dprint2(3,"\nCouldn't expand system path '%s' (%s)\n\n",
- machine, "domains");
- error1("Couldn't find a path to %s!", machine);
- sleep(2);
- return(NULL); /* failed!! */
- }
- strcat(address, expanded); /* isn't this fun??? */
-
- break;
-
- case PPATH :
-
- if ((expanded = find_path_to(path, FALSE)) == NULL) {
- dprint2(3,"\nCouldn't expand system path '%s' (%s)\n\n",
- path, "domains");
- error1("I Couldn't find a path to %s!", path);
- sleep(2);
- return(NULL); /* failed!! */
- }
- strcat(address, expanded); /* isn't this fun??? */
-
- break;
-
- case OBSOLETE: /* fall through.. */
- default : dprint2(1,
- "\nError: Bad sequence in template file for domain '%s': %%%c\n\n",
- domain, template[i]);
- }
- j = strlen(address);
- }
- else {
- address[j++] = template[i];
- address[j] = '\0'; /* null terminate */
- }
- }
-
- address[j] = '\0';
-
- } while (strlen(address) < 1);
-
- return( (char *) address);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7635 ]
- then
- echo $filename changed - should be 7635 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/fileio.c ----------
-
- filename="src/fileio.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/fileio.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** fileio.c **/
-
- /** File I/O routines, including deletion from the mailbox!
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- copy_message(prefix, dest_file, remove_header, remote)
- char *prefix;
- FILE *dest_file;
- int remove_header, remote;
- {
- /** Copy current message to destination file, with optional 'prefix'
- as the prefix for each line. If remove_header is true, it will
- skip lines in the message until it finds the end of header line...
- then it will start copying into the file... If remote is true
- then it will append "remote from <hostname>" at the end of the
- very first line of the file (for remailing) **/
-
- char buffer[LONG_SLEN];
- register int ok = 1, lines, in_header = 1, first_line = TRUE;
-
- /** get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- dprint2(1,"ERROR: Attempt to seek %d bytes into file failed (%s)",
- header_table[current-1].offset, "copy_message");
- error1("ELM [seek] failed trying to read %d bytes into file",
- header_table[current-1].offset);
- return;
- }
-
- /* how many lines in message? */
-
- lines = header_table[current-1].lines;
-
- /* now while not EOF & still in message... copy it! */
-
- while (ok && lines--) {
- ok = (int) (fgets(buffer, LONG_SLEN, mailfile) != NULL);
- if (strlen(buffer) < 2) in_header = 0;
- if (ok)
- if (! (remove_header && in_header))
- if (first_line && remote) {
- no_ret(buffer);
- fprintf(dest_file, "%s%s remote from %s\n",
- prefix, buffer, hostname);
- first_line = FALSE;
- }
- else if (! in_header && first_word(buffer, "From ")) {
- dprint0(1,"\n*** Internal Problem...Tried to add the following;\n");
- dprint1(1," '%s'\nto output file (copy_message) ***\n", buffer);
- }
- else
- fprintf(dest_file, "%s%s", prefix, buffer);
- }
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 1967 ]
- then
- echo $filename changed - should be 1967 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/return_addr.c ----------
-
- filename="src/return_addr.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/return_addr.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** return_addr.c **/
-
- /** This set of routines is used to generate real return addresses
- and also return addresses suitable for inclusion in a users
- alias files (ie optimized based on the pathalias database).
-
- Added: the ability to respond to messages that were originally
- sent by the user (That is, the "savemail" file format messages)
- by reading the return address, seeing the "To:" prefix and then
- calling the "get_existing_return()" routine. Currently this does
- NOT include any "Cc" lines in the message, just the "To:" line(s).
-
- Also added the PREFER_UUCP stuff for listing reasonable addresses
- and such...*sigh*
-
- These routines (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <errno.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *shift_lower(), *notes_machine(), *expand_address();
-
- extern int errno;
-
- char *error_name();
-
- optimize_return(address)
- char *address;
- {
- /** This routine tries to create an optimized address, that is,
- an address that has the minimal information needed to
- route a message to this person given the current path
- database...
- **/
-
- #ifdef PREFER_UUCP
-
- /** first off, let's see if we need to strip off the localhost
- address crap... **/
-
- /** if we have a uucp part (e.g.a!b) AND the bogus address...**/
-
- if (chloc(address,'!') != -1 && in_string(address, BOGUS_INTERNET))
- address[strlen(address)-strlen(BOGUS_INTERNET)] = '\0';
- #endif
-
- /** next step is to figure out what sort of address we have... **/
-
- if (chloc(address, '%') != -1)
- optimize_cmplx_arpa(address);
- else if (chloc(address, '@') != -1)
- optimize_arpa(address);
- else
- optimize_usenet(address);
- }
-
- optimize_cmplx_arpa(address)
- char *address;
- {
- /** Try to optimize a complex ARPA address. A Complex address is one
- that contains '%' (deferred '@'). For example:
- veeger!hpcnof!hplabs!joe%sytech@syte
- is a complex address (no kidding, right?). The algorithm for
- trying to resolve it is to move all the way to the right, then
- back up left until the first '!' then from there to the SECOND
- metacharacter on the right is the name@host address...(in this
- example, it would be "joe%sytech"). Check this in the routing
- table. If not present, keep backing out to the right until we
- find a host that is present, or we hit the '@' sign. Once we
- have a 'normal' ARPA address, hand it to optimize_arpa().
- **/
-
- char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
- char host[SHORT_SLEN], old_host[SHORT_SLEN];
- register int i, loc, nloc = 0, hloc = 0, passes = 1;
-
- /** first off, get the name%host... **/
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--)
- ;
-
- while (address[loc] != '\0') {
-
- if (passes == 1) {
- loc++;
-
- while (address[loc] != '%' && address[loc] != '@')
- name[nloc++] = address[loc++];
- }
- else {
- for (i=0; old_host[i] != '\0'; i++)
- name[nloc++] = old_host[i];
- }
-
- loc++;
-
- while (address[loc] != '%' && address[loc] != '@')
- host[hloc++] = address[loc++];
-
- host[hloc] = name[nloc] = '\0';
-
- strcpy(old_host, host);
- remove_domains(host);
-
- sprintf(buffer, "%s@%s", name, shift_lower(host));
-
- if (expand_site(buffer, junk) == 0) {
- strcpy(address, buffer);
- return;
- }
- else if (address[loc] == '@') {
- optimize_arpa(address);
- return;
- }
- else
- name[nloc++] = '%'; /* for next pass through */
-
- }
- }
-
- optimize_arpa(address)
- char *address;
- {
- /** Get an arpa address and simplify it to the minimal
- route needed to get mail to this person... **/
-
- char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
- char host[SHORT_SLEN];
- register int loc, nloc = 0, hloc = 0, at_sign = 0;
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--) {
- if (address[loc] == '@')
- at_sign++; /* remember this spot! */
- else if (at_sign)
- name[nloc++] = address[loc];
- else
- host[hloc++] = address[loc];
- }
-
- name[nloc] = host[hloc] = '\0';
-
- reverse(name);
- reverse(host);
-
- remove_domains(host);
-
- sprintf(buffer,"%s@%s", name, shift_lower(host));
-
- if (expand_site(buffer, junk) == 0) {
- strcpy(address, buffer);
- return;
- }
-
- optimize_usenet(address); /* that didn't work... */
- }
-
- optimize_usenet(address)
- char *address;
- {
- /** optimize the return address IFF it's a standard usenet
- address...
- **/
-
- char name[SHORT_SLEN], new_address[SLEN], buffer[SLEN], junk[SLEN];
- register int loc, nloc = 0, aloc = 0, passes = 1;
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--)
- name[nloc++] = address[loc];
- name[nloc] = '\0';
-
- reverse(name);
-
- new_address[0] = '\0';
-
- /* got name, now get machine until we can get outta here */
-
- while (loc > -1) {
-
- new_address[aloc++] = address[loc--]; /* the '!' char */
-
- while (address[loc] != '!' && loc > -1)
- new_address[aloc++] = address[loc--];
-
- new_address[aloc] = '\0';
-
- strcpy(buffer, new_address);
- reverse(buffer);
-
- if (expand_site(buffer, junk) == 0) {
- if (passes == 1 && chloc(name, '@') == -1) {
- buffer[strlen(buffer) - 1] = '\0'; /* remove '!' */
- sprintf(address, "%s@%s", name, buffer);
- }
- else
- sprintf(address, "%s%s", buffer, name);
- return; /* success! */
- }
- passes++;
- }
-
- return; /* nothing to do! */
- }
-
- get_return(buffer)
- char *buffer;
- {
- /** reads 'current' message again, building up the full return
- address including all machines that might have forwarded
- the message. **/
-
- char buf[LONG_SLEN], name1[SLEN], name2[SLEN], lastname[SLEN];
- char hold_return[LONG_SLEN], alt_name2[SLEN];
- int ok = 1, lines;
-
- /** are we reading a notesfile file?? **/
-
- if (notesfile) {
- strcpy(buf, header_table[current-1].from);
- if (chloc(buf, '!') == -1)
- sprintf(buf, "%s!%s", notes_machine(), header_table[current-1].from);
- strcpy(buffer, expand_system(buf, TRUE));
- return;
- }
-
- /** get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- dprint3(1,"Error: seek %ld bytes into file hit errno %s (%s)",
- header_table[current-1].offset, error_name(errno),
- "get_return");
- error2("couldn't seek %d bytes into file (%s)",
- header_table[current-1].offset, error_name(errno));
- return;
- }
-
- /** okay! Now we're there! **/
-
- lines = header_table[current-1].lines;
-
- buffer[0] = '\0';
-
- while (ok && lines--) {
- ok = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
- if (first_word(buf, "From ")) {
- sscanf(buf, "%*s %s", hold_return);
- }
- else if (first_word(buf, ">From")) {
- sscanf(buf,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s %s",
- name1, name2, alt_name2);
- if (strcmp(name2, "from") == 0)
- strcpy(name2, alt_name2);
- add_site(buffer, name2, lastname);
- }
-
- #ifdef USE_EMBEDDED_ADDRESSES
-
- else if (first_word(buf, "From:")) {
- get_address_from("From:", buf, hold_return);
- }
- else if (first_word(buf, "Reply-To:")) {
- get_address_from("Reply-To:", buf, buffer);
- return;
- }
-
- #endif
-
- else if (strlen(buf) < 2) /* done with header */
- lines = 0; /* let's get outta here! We're done!!! */
- }
-
- if (buffer[0] == '\0')
- strcpy(buffer, hold_return); /* default address! */
- else
- add_site(buffer, name1, lastname); /* get the user name too! */
-
- if (first_word(buffer, "To:")) /* response to savecopy! */
- get_existing_address(buffer);
- }
-
- get_existing_address(buffer)
- char *buffer;
- {
- /** This routine is called when the message being responded to has
- "To:xyz" as the return address, signifying that this message is
- an automatically saved copy of a message previously sent. The
- correct to address can be obtained fairly simply by reading the
- To: header from the message itself and (blindly) copying it to
- the given buffer. Note that this header can be either a normal
- "To:" line (Elm) or "Originally-To:" (previous versions e.g.Msg)
- **/
-
- char mybuf[LONG_STRING];
- register char ok = 1, in_to = 0;
-
- buffer[0] = '\0';
-
- /** first off, let's get to the beginning of the message... **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- dprint3(1,"Error: seek %ld bytes into file hit errno %s (%s)",
- header_table[current-1].offset, error_name(errno),
- "get_existing_address");
- error2("couldn't seek %d bytes into the file (%s)",
- header_table[current-1].offset, error_name(errno));
- return;
- }
-
- /** okay! Now we're there! **/
-
- while (ok) {
- ok = (int) (fgets(mybuf, LONG_STRING, mailfile) != NULL);
- no_ret(mybuf); /* remove return character */
-
- if (first_word(mybuf, "To: ")) {
- in_to = TRUE;
- strcpy(buffer, (char *) mybuf + strlen("To: "));
- }
- else if (first_word(mybuf, "Original-To:")) {
- in_to = TRUE;
- strcpy(buffer, (char *) mybuf + strlen("Original-To:"));
- }
- else if (in_to && whitespace(mybuf[0])) {
- strcat(buffer, " "); /* tag a space in */
- strcat(buffer, (char *) mybuf + 1); /* skip 1 whitespace */
- }
- else if (strlen(mybuf) < 2)
- return; /* we're done for! */
- else
- in_to = 0;
- }
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 9321 ]
- then
- echo $filename changed - should be 9321 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/addr_utils.c ----------
-
- filename="src/addr_utils.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/addr_utils.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** addr_utils.c **/
-
- /** This file contains addressing utilities
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- char *shift_lower(), *get_alias_address(), *get_token(), *strtok();
-
- int
- talk_to(sitename)
- char *sitename;
- {
- /** If we talk to the specified site, return true, else
- we're going to have to expand this baby out, so
- return false! **/
-
- struct lsys_rec *sysname;
-
- sysname = talk_to_sys;
-
- if (sysname == NULL) {
- dprint0(2,
- "Warning - talk_to_sys is currently set to NULL! (talk_to)\n");
- return(0);
- }
-
- while (sysname != NULL) {
- if (strcmp(sysname->name, sitename) == 0)
- return(1);
- else
- sysname = sysname->next;
- }
-
- return(0);
- }
-
- remove_domains(host)
- char *host;
- {
- /** Remove all entries following the first '.' to ensure that
- entries like "MIT.ARPA" will match "MIT" in the database
- **/
-
- register int loc = 0;
-
- while (host[loc] != '.' && host[loc] != '\0')
- loc++;
-
- if (host[loc] == '.') host[loc] = '\0';
- }
-
- add_site(buffer, site, lastsite)
- char *buffer, *site, *lastsite;
- {
- /** add site to buffer, unless site is 'uucp', current machine, or
- site is the same as lastsite. If not, set lastsite to
- site.
- **/
-
- char local_buffer[LONG_SLEN];
-
- if (strcmp(site, "uucp") != 0)
- if (strcmp(site, lastsite) != 0)
- if (strcmp(site, hostname) != 0) {
- if (buffer[0] == '\0')
- strcpy(buffer, strip_parens(site)); /* first in list! */
- else {
- sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
- strcpy(buffer, local_buffer);
- }
- strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
- }
- }
-
- #ifdef USE_EMBEDDED_ADDRESSES
-
- get_address_from(prefix, line, buffer)
- char *prefix, *line, *buffer;
- {
- /** This routine extracts the address from either a 'From:' line
- or a 'Reply-To:' line...the algorithm is quite simple, too:
- increment 'line' past header, then check last character of
- line. If it's a '>' then the address is contained within '<>'
- and if it's a ')' then the address is in the 'clear'... **/
-
- register int i, j = 0;
-
- no_ret(line);
-
- line = (char *) (line + strlen(prefix) + 1);
-
- if (line[strlen(line)-1] == '>') {
- for (i=strlen(line)-2; i > -1 && line[i] != '<'; i--)
- buffer[j++] = line[i];
- buffer[j] = 0;
- reverse(buffer);
- }
- else { /* either ')' or address in the clear... */
- for (i=0; i < strlen(line) && line[i] != '('; i++)
- buffer[j++] = line[i];
- if (buffer[j-1] == '(') j--;
- buffer[j] = 0;
- }
- }
-
- #endif
-
- translate_return(addr, ret_addr)
- char *addr, *ret_addr;
- {
- /** Return ret_addr to be the same as addr, but with the login
- of the person sending the message replaced by '%s' for
- future processing...
- Fixed to make "%xx" "%%xx" (dumb 'C' system!)
- **/
-
- register int loc, loc2, index = 0;
-
- loc2 = chloc(addr,'@');
- if ((loc = chloc(addr, '%')) < loc2)
- loc2 = loc;
-
- if (loc2 != -1) { /* ARPA address. */
- /* algorithm is to get to '@' sign and move backwards until
- we've hit the beginning of the word or another metachar.
- */
- for (loc = loc2 - 1; loc > -1 && addr[loc] != '!'; loc--)
- ;
- }
- else { /* usenet address */
- /* simple algorithm - find last '!' */
-
- loc2 = strlen(addr); /* need it anyway! */
-
- for (loc = loc2; loc > -1 && addr[loc] != '!'; loc--)
- ;
- }
-
- /** now copy up to 'loc' into destination... **/
-
- while (index <= loc) {
- ret_addr[index] = addr[index];
- index++;
- }
-
- /** now append the '%s'... **/
-
- ret_addr[index++] = '%';
- ret_addr[index++] = 's';
-
- /** and, finally, if anything left, add that **/
-
- while (loc2 < strlen(addr)) {
- ret_addr[index++] = addr[loc2++];
- if (addr[loc2-1] == '%') /* tweak for "printf" */
- ret_addr[index++] = '%';
- }
-
- ret_addr[index] = '\0';
- }
-
- build_address(to, full_to)
- char *to, *full_to;
- {
- /** loop on all words in 'to' line...append to full_to as
- we go along, until done or length > len **/
-
- register int i, changed = 0;
- char word[SLEN], *ptr, buffer[SLEN];
- char new_to_list[LONG_SLEN];
-
- new_to_list[0] = '\0';
-
- i = get_word(to, 0, word);
-
- full_to[0] = '\0';
-
- while (i > 0) {
-
- if (strpbrk(word,"!@:") != NULL)
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", expand_system(word, 1));
- else if ((ptr = get_alias_address(word, 1, 0)) != NULL)
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", ptr);
- else if (strlen(word) > 0) {
- if (valid_name(word))
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", word);
- else if (check_only) {
- printf("(alias \"%s\" is unknown)\n\r",
- word);
- changed++;
- }
- else if (! isatty(fileno(stdin)) ) { /* batch mode error! */
- fprintf(stderr,"Cannot expand alias '%s'!\n\r", word);
- fprintf(stderr,"Use \"checkalias\" to find valid addresses!\n\r");
- dprint1(1,
- "Can't expand alias %s - bailing out! (build_address)\n",
- word);
- emergency_exit();
- }
- else {
- dprint1(2,"Entered unknown address %s (build_address)\n", word);
- sprintf(buffer, "'%s' is an unknown address. Replace with: ",
- word);
- word[0] = '\0';
- if (! mail_only)
- PutLine0(LINES, 0, buffer);
-
- (void) optionally_enter(word, LINES, strlen(buffer), FALSE);
- if (strlen(word) > 0) {
- sprintf(new_to_list, "%s%s%s", new_to_list,
- strlen(new_to_list) > 0? " ":"", word);
- dprint1(3,"Replaced with %s (build_address)\n", word);
- }
- else
- dprint0(3,"Address removed from to list (build_address)\n");
- if (mail_only) printf("\n\r");
- changed++;
- clear_error();
- continue;
- }
- }
-
- i = get_word(to, i, word);
- }
-
- if (changed)
- strcpy(to, new_to_list);
- }
-
- int
- real_from(buffer, entry)
- char *buffer;
- struct header_rec *entry;
- {
- /***** Returns true iff 's' has the seven 'from' fields, (or
- 8 - some machines include the TIME ZONE!!!)
- Initializing the date and from entries in the record
- and also the message received date/time. *****/
-
- char junk[STRING], timebuff[STRING], holding_from[SLEN];
- int eight_fields = 0;
-
- entry->year[0] = '\0';
- junk[0] = '\0';
-
- /* From <user> <day> <month> <day> <hr:min:sec> <year> */
-
- sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %s", timebuff, junk);
-
- if (timebuff[1] != ':' && timebuff[2] != ':') {
- dprint1(3,"real_from returns FAIL [bad time field] on\n-> %s\n",
- buffer);
- return(FALSE);
- }
- if (junk[0] != '\0') { /* try for 8 field entry */
- junk[0] = '\0';
- sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %*s %s", timebuff, junk);
- if (junk[0] != '\0') {
- dprint1(3,"real_from returns FAIL [too many fields] on\n-> %s\n",
- buffer);
- return(FALSE);
- }
- eight_fields++;
- }
-
- /** now get the info out of the record! **/
-
- if (eight_fields)
- sscanf(buffer, "%s %s %s %s %s %s %*s %s",
- junk, holding_from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year);
- else
- sscanf(buffer, "%s %s %s %s %s %s %s",
- junk, holding_from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year);
-
- strncpy(entry->from, holding_from, STRING);
- resolve_received(entry);
- return(entry->year[0] != '\0');
- }
-
- forwarded(buffer, entry)
- char *buffer;
- struct header_rec *entry;
- {
- /** Change 'from' and date fields to reflect the ORIGINATOR of
- the message by iteratively parsing the >From fields...
- Modified to deal with headers that include the time zone
- of the originating machine... **/
-
- char machine[SLEN], buff[SLEN], holding_from[SLEN];
-
- machine[0] = '\0';
-
- sscanf(buffer, "%*s %s %s %s %s %s %s %*s %*s %s",
- holding_from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year, machine);
-
- if (isdigit(entry->month[0])) { /* try for veeger address */
- sscanf(buffer, "%*s %s %s%*c %s %s %s %s %*s %*s %s",
- holding_from, entry->dayname, entry->day, entry->month,
- entry->year, entry->time, machine);
- }
- if (isalpha(entry->year[0])) { /* try for address including tz */
- sscanf(buffer, "%*s %s %s %s %s %s %*s %s %*s %*s %s",
- holding_from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year, machine);
- }
-
- if (machine[0] == '\0')
- sprintf(buff,"anonymous");
- else
- sprintf(buff,"%s!%s", machine, holding_from);
-
- strncpy(entry->from, buff, STRING);
- }
-
- parse_arpa_from(buffer, newfrom)
- char *buffer, *newfrom;
- {
- /** try to parse the 'From:' line given... It can be in one of
- two formats:
- From: Dave Taylor <hplabs!dat>
- or From: hplabs!dat (Dave Taylor)
-
- Change 'newfrom' ONLY if sucessfully parsed this entry and
- the resulting name is non-null!
- Added: removes quotes if name is quoted (12/12)
- Added: only copies STRING characters...
- **/
-
- char temp_buffer[SLEN], *temp;
- register int i, j = 0;
-
- temp = (char *) temp_buffer;
- temp[0] = '\0';
-
- no_ret(buffer); /* blow away '\n' char! */
-
- if (lastch(buffer) == '>') {
- for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- buffer[i] != '('; i++)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- }
- else if (lastch(buffer) == ')') {
- for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
- buffer[i] != '<'; i--)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- reverse(temp);
- }
-
- if (strlen(temp) > 0) { /* mess with buffer... */
-
- /* remove leading spaces and quotes... */
-
- while (whitespace(temp[0]) || quote(temp[0]))
- temp = (char *) (temp + 1); /* increment address! */
-
- /* remove trailing spaces and quotes... */
-
- i = strlen(temp) - 1;
-
- while (whitespace(temp[i]) || quote(temp[i]))
- temp[i--] = '\0';
-
- /* if anything is left, let's change 'from' value! */
-
- if (strlen(temp) > 0)
- strncpy(newfrom, temp, STRING);
- }
- }
-
- parse_arpa_date(string, entry)
- char *string;
- struct header_rec *entry;
- {
- /** Parse and figure out the given date format... return
- the entry fields changed iff it turns out we have a
- valid parse of the date! **/
-
- char word[15][NLEN], buffer[SLEN], *bufptr;
- char *aword;
- int words = 0;
-
- strcpy(buffer, string);
- bufptr = (char *) buffer;
-
- /** break the line down into words... **/
-
- while ((aword = strtok(bufptr," \t '\"-/(),.")) != NULL) {
- strcpy(word[words++], aword);
- bufptr = NULL;
- }
-
- if (words < 6) { /* strange format. We're outta here! */
- dprint1(3,"parse_arpa_date failed [less than six fields] on\n-> %s\n",
- string);
- return;
- }
-
- /* There are now five possible combinations that we could have:
-
- Date: day_number month_name year_number time timezone
- Date: day_name day_number month_name year_number ...
- Date: day_name month_name day_number time year_number
- Date: day_name month_name day_number year_number time
- Date: day_number month_name year_number time timezone day_name
-
- Note that they are distinguishable by checking the first
- character of the second, third and fourth words...
- */
-
- if (isdigit(word[1][0])) { /*** type one! ***/
- if (! valid_date(word[1], word[2], word[3])) {
- dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
- word[1], word[2], word[3], string);
- return; /* strange date! */
- }
- strncpy(entry->day, word[1], 3);
- strncpy(entry->month, word[2], 3);
- strncpy(entry->year, word[3], 4);
- strncpy(entry->time, word[4], 10);
- }
- else if (isdigit(word[2][0])) { /*** type two! ***/
- if (! valid_date(word[2], word[3], word[4])) {
- dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
- word[2], word[3], word[4], string);
- return; /* strange date! */
- }
- strncpy(entry->day, word[2], 3);
- strncpy(entry->month, word[3], 3);
- strncpy(entry->year, word[4], 4);
- strncpy(entry->time, word[5], 10);
- }
- else if (isdigit(word[3][0])) {
- if (word[4][1] == ':' ||
- word[4][2] == ':') { /*** type three! ***/
- if (! valid_date(word[3], word[2], word[5])) {
- dprint4(3,
- "parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
- word[3], word[2], word[5], string);
- return; /* strange date! */
- }
- strncpy(entry->year, word[5], 4);
- strncpy(entry->time, word[4], 10);
- }
- else { /*** type four! ***/
- if (! valid_date(word[3], word[2], word[4])) {
- dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
- word[3], word[2], word[4], string);
- return; /* strange date! */
- }
- strncpy(entry->year, word[4], 4);
- strncpy(entry->time, word[5], 10);
- }
- strncpy(entry->day, word[3], 3);
- strncpy(entry->month, word[2], 3);
- }
- }
-
- fix_arpa_address(address)
- char *address;
- {
- /** Given a pure ARPA address, try to make it reasonable.
-
- This means that if you have something of the form a@b@b make
- it a@b. If you have something like a%b%c%b@x make it a%b@x...
- **/
-
- register int host_count = 0, i;
- char hosts[MAX_HOPS][2*NLEN]; /* array of machine names */
- char *host, *addrptr;
-
- /* break down into a list of machine names, checking as we go along */
-
- addrptr = (char *) address;
-
- while ((host = get_token(addrptr, "%@", 2)) != NULL) {
- for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
- ;
-
- if (i == host_count) {
- strcpy(hosts[host_count++], host);
- if (host_count == MAX_HOPS) {
- dprint0(2,
- "Can't build return address - hit MAX_HOPS (fix_arpa_address)\n");
- error("Can't build return address - hit MAX_HOPS limit!");
- return(1);
- }
- }
- else
- host_count = i + 1;
- addrptr = NULL;
- }
-
- /** rebuild the address.. **/
-
- address[0] = '\0';
-
- for (i = 0; i < host_count; i++)
- sprintf(address, "%s%s%s", address,
- address[0] == '\0'? "" :
- (i == host_count - 1 ? "@" : "%"),
- hosts[i]);
-
- return(0);
- }
-
- figure_out_addressee(buffer, mail_to)
- char *buffer;
- char *mail_to;
- {
- /** This routine steps through all the addresses in the "To:"
- list, initially setting it to the first entry (if mail_to
- is NULL) or, if the user is found (eg "alternatives") to
- the current "username".
-
- Modified to know how to read quoted names...
- **/
-
- char *address, *bufptr, *strchr();
- register int index = 0, index2 = 0;
-
- if (equal(mail_to, username)) return; /* can't be better! */
-
- bufptr = (char *) buffer; /* use the string directly */
-
- if (strchr(buffer,'"') != NULL) { /* we have a quoted string */
- while (buffer[index] != '"')
- index++;
- index++; /* skip the leading quote */
- while (buffer[index] != '"' && index < strlen(buffer))
- mail_to[index2++] = buffer[index++];
- mail_to[index2] = '\0';
- }
- else while ((address = strtok(bufptr, " ,\t\n\r")) != NULL) {
- if (! okay_address(address, "don't match me!")) {
- strcpy(mail_to, username); /* it's to YOU! */
- return;
- }
- else if (strlen(mail_to) == 0) /* it's SOMEthing! */
- get_return_name(address, mail_to, FALSE);
-
- bufptr = (char *) NULL; /* set to null */
- }
-
- return;
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 15408 ]
- then
- echo $filename changed - should be 15408 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/input_utils.c ----------
-
- filename="src/input_utils.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/input_utils.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** input_utils.c **/
-
- /** Mindless I/O routines for ELM
-
- (C) Copyright 1985 Dave Taylor
- **/
-
- #include "headers.h"
- #include <errno.h>
-
- extern int errno; /* system error number */
-
- int
- want_to(question, dflt, echo_answer)
- char *question, dflt;
- int echo_answer;
- {
- /** Ask 'question' at LINES-2, COLUMNS-40, returning the answer in
- lower case. If 'echo_answer', then echo answer. 'dflt' is the
- default answer if <return> is pressed. (Note: 'dflt' is also what
- will be returned if <return> is pressed!)
- **/
- register char ch, cols;
-
- cols = (strlen(question) < 30)? COLUMNS-40 : COLUMNS-50;
-
- PutLine3(LINES-3, cols,"%s%c%c", question, dflt, BACKSPACE);
- fflush(stdout);
- fflush(stdin);
- ch = tolower(ReadCh());
-
- if (echo_answer && ch > (char) ' ') {
- Writechar(ch);
- fflush(stdout);
- }
-
- return(ch == '\n' || ch == '\r' ? dflt : ch);
- }
-
- int
- read_number(ch, max)
- char ch;
- int max;
- {
- /** read a number, where 'ch' is the leading digit!
- If max < 10 then just return 'ch' **/
-
- char buff[SHORT_SLEN];
- int num;
-
- if (max < 10)
- return( (int) ch - '0' );
-
- buff[0] = ch;
- buff[1] = '\0';
-
- PutLine0(LINES-3, COLUMNS-40,"Set current message to :");
- if (optionally_enter(buff, LINES-3, COLUMNS-15, TRUE) == -1)
- return(current);
-
- sscanf(buff,"%d", &num);
- return(num);
- }
-
- int
- optionally_enter(string, x, y, append_current)
- char *string;
- int x,y, append_current;
- {
- /** Display the string on the screen and if RETURN is pressed, return
- it. Otherwise, allow standard text input, including backspaces
- and such until RETURN is hit.
- If "append_current" is set, then leave the default string in
- place and edit AFTER it...assume 'x,y' is placing us at the
- beginning of the string...
- This routine returns zero unless INTERRUPT hit, then it returns
- -1 and must be treated accordingly.
- **/
-
- char ch;
- register index = 0;
-
- PutLine1(x,y, "%s", string);
- CleartoEOLN();
- if (! append_current)
- MoveCursor(x,y);
-
- if (cursor_control)
- transmit_functions(OFF);
-
- ch = getchar();
-
- if (ch == '\n' || ch == '\r') {
- if (cursor_control)
- transmit_functions(ON);
- return(0); /* we're done. No change needed */
- }
-
- CleartoEOLN();
-
- index = (append_current? strlen(string) : 0);
-
- if (ch == kill_line) {
- if (! mail_only)
- MoveCursor(x,y);
- CleartoEOLN();
- index = 0;
- }
- else if (ch != backspace) {
- Writechar(ch);
- string[index++] = ch;
- }
- else if (index > 0) {
- index--;
- Writechar(BACKSPACE);
- Writechar(' ');
- Writechar(BACKSPACE);
- fflush(stdout);
- }
- else {
- Writechar(' ');
- Writechar(BACKSPACE);
- fflush(stdout);
- }
-
- do {
- ch = getchar();
-
- /* the following is converted from a case statement to
- allow the variable characters (backspace, kill_line
- and break) to be processed. Case statements in
- C require constants as labels, so it failed ...
- */
-
- if (ch == backspace) {
- if (index > 0) {
- index--;
- Writechar(BACKSPACE);
- Writechar(' ');
- Writechar(BACKSPACE);
- fflush(stdout);
- }
- else {
- Writechar(' ');
- Writechar(BACKSPACE);
- fflush(stdout);
- }
- }
- else if (ch == '\n' || ch == '\r') {
- string[index] = '\0';
- if (cursor_control)
- transmit_functions(ON);
- return(0);
- }
- else if (ch == kill_line) {
- if (mail_only)
- back_up(index+1);
- else
- MoveCursor(x,y);
- CleartoEOLN();
- index = 0;
- }
- else if (ch == NULL) {
- if (cursor_control)
- transmit_functions(ON);
- fflush(stdin); /* remove extraneous chars, if any */
- string[0] = '\0'; /* clean up string, and... */
- return(-1);
- }
- else { /* default case */
-
- string[index++] = ch;
- Writechar(ch);
- }
- } while (index < SLEN);
-
- string[index] = '\0';
-
- if (cursor_control)
- transmit_functions(ON);
- return(0);
- }
-
-
- int
- pattern_enter(string, alt_string, x, y, alternate_prompt)
- char *string, *alt_string, *alternate_prompt;
- int x,y;
- {
- /** This function is functionally similar to the routine
- optionally-enter, but if the first character pressed
- is a '/' character, then the alternate prompt and string
- are used rather than the normal one. This routine
- returns 1 if alternate was used, 0 if not
- **/
-
- char ch;
- register index = 0;
-
- PutLine1(x, y, "%s", string);
- CleartoEOLN();
- MoveCursor(x,y);
-
- if (cursor_control)
- transmit_functions(OFF);
-
- ch = getchar();
-
- if (ch == '\n' || ch == '\r') {
- if (cursor_control)
- transmit_functions(ON);
- return(0); /* we're done. No change needed */
- }
-
- if (ch == '/') {
- PutLine1(x, 0, "%s", alternate_prompt);
- CleartoEOLN();
- (void) optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
- FALSE);
- return(1);
- }
-
- CleartoEOLN();
-
- index = 0;
-
- if (ch == kill_line) {
- MoveCursor(x,y);
- CleartoEOLN();
- index = 0;
- }
- else if (ch != backspace) {
- Writechar(ch);
- string[index++] = ch;
- }
- else if (index > 0) {
- index--;
- Writechar(BACKSPACE);
- Writechar(' ');
- Writechar(BACKSPACE);
- }
- else {
- Writechar(' ');
- Writechar(BACKSPACE);
- }
-
- do {
- fflush(stdout);
- ch = getchar();
-
- /* the following is converted from a case statement to
- allow the variable characters (backspace, kill_line
- and break) to be processed. Case statements in
- C require constants as labels, so it failed ...
- */
-
- if (ch == backspace) {
- if (index > 0) {
- index--;
- Writechar(BACKSPACE);
- Writechar(' ');
- Writechar(BACKSPACE);
- }
- else {
- Writechar(' ');
- Writechar(BACKSPACE);
- }
- }
- else if (ch == '\n' || ch == '\r') {
- string[index] = '\0';
- if (cursor_control)
- transmit_functions(ON);
- return(0);
- }
- else if (ch == kill_line) {
- MoveCursor(x,y);
- CleartoEOLN();
- index = 0;
- }
- else if (ch == NULL) {
- if (cursor_control)
- transmit_functions(ON);
- fflush(stdin); /* remove extraneous chars, if any */
- string[0] = '\0'; /* clean up string, and... */
- return(-1);
- }
- else { /* default case */
-
- string[index++] = ch;
- Writechar(ch);
- }
- } while (index < SLEN);
-
- string[index] = '\0';
-
- if (cursor_control)
- transmit_functions(ON);
- return(0);
- }
-
- back_up(spaces)
- int spaces;
- {
- /** this routine is to replace the goto x,y call for when sending
- mail without starting the entire "elm" system up... **/
-
- while (spaces--) {
- Writechar(BACKSPACE);
- Writechar(' ');
- Writechar(BACKSPACE);
- }
-
- fflush(stdout);
- }
-
- int
- GetPrompt()
- {
- /** This routine does a read/timeout for a single character.
- The way that this is determined is that the routine to
- read a character is called, then the "errno" is checked
- against EINTR (interrupted call). If they match, this
- returns NO_OP_COMMAND otherwise it returns the normal
- command.
- **/
-
- int ch;
-
- if (timeout > 0) {
- alarm(timeout);
- errno = 0; /* we actually have to do this. *sigh* */
- ch = ReadCh();
- if (errno == EINTR) ch = NO_OP_COMMAND;
- alarm(0);
- }
- else
- ch = ReadCh();
-
- return(ch);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7235 ]
- then
- echo $filename changed - should be 7235 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- echo end of this archive file....
- exit 0
-
-