home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i058: Elm fixes for BSD, et. al. (elm/Patches1)
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <cca!HPLABS.HP.COM!taylor@hpldat>
- Mod.sources: Volume 6, Issue 58
- Archive-name: elm/Patches1
-
-
- Fixes to Elm version 1.1, as posted to mod.sources
-
- [last update 7/14/86]
-
- Notationally, any lines that have an asterisk in the first column are those
- that have changed in one way or another. The asterisk shouldn't be part of
- what's actually typed in, needless to say!
-
- Secondly, when you've applied this set of patches, you should go into the
- file "hdrs/defs.h" and change the VERSION number from 1.1 to 1.2, and change
- the what_string line to;
- ------------
- #define WHAT_STRING "@(#) Version 1.2, patch #1 release - July 1986"
- -----------
- Don't do it until the patches and Enhancement(s) have all been added,
- though.
-
-
- Documentation glitches;
-
- 1. In the file "doc/elm.1" the flags listing should read;
- --------------
- * .TP
- .B "-c"
- Checkalias - expand the following aliases and return.
- * .TP
- .B "-d <level>"
- Debug - set specified debug level - Output to "$HOME/Elm:debug.info"
- --------------
-
- 2. In the main Makefile, the configuration guide formatting should be;
- --------------
- doc/Config.fmtd: doc/Config.guide
- * ${TBL} doc/Config.guide | ${FORMATTER} -mm > doc/Config.fmtd
- --------------
-
-
- Makefile problems;
-
- 1. see #2 above
-
- 2. In the main Makefile, the multiple arguments need to be quoted
- for some systems, to wit;
- --------------
- # else if on a Sun system:
- * # DEFINE = "-DBSD -DSUN"
- # LIB2 = -lcurses
- # else if on a Pyramid system:
- * # DEFINE = "-DBSD -DNO_VAR_ARGS"
- -------------
- and
- -------------
- * # DEFINE="${DEFINE} -DACSNET"
- --------------
-
- Utility problems;
-
- 1. In the Utilities makefile, the checkalias generation line to;
- --------------
- * @echo 'exec elm -c $$*' >> ../bin/checkalias
- --------------
-
- 2. in newmail.c and wnewmail.c move the lines;
- --------------
- #ifdef AUTO_BACKGROUND
- # include <signal.h> /* background jobs ignore some signals... */
- #endif
- --------------
- to occur AFTER the include for "defs.h". Otherwise it'll just
- get hopelessly confused.
-
- 3. In the file arepdaemon.c, change the header declarations to;
- --------------
- * #ifdef BSD
- * # include <sys/time.h>
- * #else
- # include <time.h>
- * #endif
- --------------
- and remove the definition ->in this file<- of the constant "NLEN",
- which is defined in the included file "defs.h". This will clear
- up some compile-time problems on BSD systems...
-
- 4. In the file autoreply.c, remove the macro definition for the constant
- READ_ACCESS (that is, remove the line "#define READ_ACCESS 04")
-
- Elm system problems;
-
- 1. In the file src/showmsg.c, change the line just before the display()
- function to;
- --------------
- FILE *output_pipe,
- * *popen();
- --------------
- This will eliminate the "illegal combination of pointer and integer"
- message encountered when compiling this routine.
-
- 2. In the file src/getopt.c, change the lines;
- --------------
- if (argv[_argnum] == NULL && _indx > 1) { /* Sun compatability */
- _argnum++;
- _indx = 1; /* zeroeth char is '-' */
- }
- * else if (argv[_argnum] != NULL)
- if (_indx >= strlen(argv[_argnum]) && _indx > 1) {
- _argnum++;
- _indx = 1; /* zeroeth char is '-' */
- }
- ---------------
- This will eliminate the Bus Error encountered on the Sun systems
- and some BSD systems...
-
- While in this file, change all compares against 'argc' from being '>'
- to being '>=' (that is, change the two occurances of the line
- "if (_argnum > argc) {" to "if (_argnum >= argc) {"
-
-
- 3. In the file "src/date.c" change the lines;
- ---------------
- * minute1 = minute2 = -1;
-
- sscanf(rec1->time, "%d:%d", &hour1, &minute1);
- sscanf(rec2->time, "%d:%d", &hour2, &minute2);
-
- * if (minute1 == -1)
- * sscanf(rec1->time, "%2d%2d", &hour1, &minute1);
-
- * if (minute2 == -1)
- * sscanf(rec2->time, "%2d%2d", &hour2, &minute2);
-
- if (hour1 != hour2)
- return( hour1 - hour2 );
-
- * return( minute1 - minute2 ); /* ignore seconds... */
- ----------------
-
- 4. In the file "src/hdrconfg.c" add....
- ----------------
- switch (c) {
- * case ctrl('J'):
- case ctrl('M'):
- case 'Q' : goto outta_here;
- ----------------
-
- MORE importantly - and this one causes a 'bus error' on BSD systems!!
- alter the case 'I' line to read;
- ----------------
- * case 'I' : if (strlen(in_reply_to) > 0) {
- if (optionally_enter(in_reply_to, 11,13, FALSE) == -1)
- goto outta_here;
- break;
- }
- ----------------
- [the change is in the location of the innermost right paren on the
- call to 'strlen' on the first line of this case entry...!]
-
- 5. In the file src/initialize.c, alter the figure out lines setting to;
- ----------------
- * ScreenSize(&LINES, &COLUMNS);
-
- if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
- sscanf(cp, "%d", &LINES);
- LINES -= 1; /* kludge for HP Window system? ... */
- }
- ----------------
- and remove the call to "ScreenSize()" from the file "src/elm.c"
-
- 6. In the file src/elm.c, remove the call to ScreenSize() (see #5)
-
- Also, change the cases for '+' and '-' to read;
- -----------------
- case ' ' :
- case '+' : header_page++; nuhead++;
- if (move_when_paged &&
- * header_page <=(message_count / headers_per_page))
- current = header_page*headers_per_page + 1;
- break;
-
- case '-' : header_page--; nuhead++;
- * if (move_when_paged && header_page >= 0)
- current = header_page*headers_per_page + 1;
- break;
- -----------------
- [the change is the tests to see what page we're on have become '<='
- from '<' and '>=' from '>' respectively...]
-
- 7. In the file src/screen.c, replace sprintf with the following;
- -----------------
- sprintf(buffer, "%s%s%c%c%c%-3d %3.3s %-2d %-18.18s (%d) %s%s%s",
- * highlight? ((has_highlighting && !arrow_cursor) ?
- * start_highlight : "->") : " ",
- * (highlight && has_highlighting && !arrow_cursor)? " " : "",
- show_status(entry->status),
- (entry->status & DELETED? 'D' : ' '),
- (entry->status & TAGGED? '+' : ' '),
- message_number,
- entry->month,
- atoi(entry->day),
- from,
- entry->lines,
- (entry->lines / 1000 > 0? "" : /* spacing the */
- entry->lines / 100 > 0? " " : /* same for the */
- entry->lines / 10 > 0? " " : /* lines in () */
- " "), /* [wierd] */
- subj,
- * (highlight && has_highlighting && !arrow_cursor) ?
- * end_highlight : "");
- -----------------
-
- 8. In the file src/delete.c change the following routines to be what's
- listed here...
- ------------------
- show_msg_status(msg)
- int msg;
- {
- /** show the status of the current message only. **/
-
- if (on_page(msg)) {
- MoveCursor((msg % headers_per_page) + 4, 3);
- * if (msg == current && !arrow_cursor) {
- * StartBold();
- * Writechar(ison(header_table[msg].status,DELETED)?'D':' ');
- * EndBold();
- * }
- * else
- Writechar(ison(header_table[msg].status,DELETED)?'D':' ');
- }
- }
- -----------------
- show_msg_tag(msg)
- int msg;
- {
- /** show the tag status of the current message only. **/
-
- if (on_page(msg)) {
- MoveCursor((msg % headers_per_page) + 4, 4);
- * if (msg == current && !arrow_cursor) {
- * StartBold();
- * Writechar(ison(header_table[msg].status,TAGGED)? '+' : ' ');
- * EndBold();
- * }
- * else
- Writechar(ison(header_table[msg].status,TAGGED)? '+' : ' ');
- }
- }
-
- show_new_status(msg)
- int msg;
- {
- /** If the specified message is on this screen, show
- the new status (could be marked for deletion now,
- and could have tag removed...)
- **/
-
- if (on_page(msg))
- * if (msg == current && !arrow_cursor) {
- * StartBold();
- * PutLine2((msg % headers_per_page) + 4, 3, "%c%c",
- * ison(header_table[msg].status, DELETED)? 'D' : ' ',
- * ison(header_table[msg].status, TAGGED )? '+' : ' ');
- * EndBold();
- * }
- * else
- PutLine2((msg % headers_per_page) + 4, 3, "%c%c",
- ison(header_table[msg].status, DELETED)? 'D' : ' ',
- ison(header_table[msg].status, TAGGED )? '+' : ' ');
- }
- ------------
-
- 9. in src/newmbox.c change;
- ------------
- (void) fclose(mailfile); /* close it first, to avoid too many open */
- ------------
- to;
- ------------
- * if (mailfile != NULL)
- (void) fclose(mailfile); /* close it first, to avoid too many open */
- ------------
-
- 10. In the files src/help.c src/date.c src/initialize.c and src/domains.c
- make sure both 'toupper' and 'tolower' are undefined if we're on a
- BSD system;
- -------------
- * #ifdef BSD
- * # undef tolower
- * # undef toupper
- * #endif
- -------------
-
- 11. In the file src/file_utils.c change the following; At the top of the
- file include the three lines;
- -------------
- * #ifdef BSD
- * #include <sys/wait.h>
- * #endif
- -------------
- and further in the file replace the existing "can_access()" with;
- -------------
- int
- can_access(file, mode)
- char *file;
- int mode;
- {
- /** returns ZERO iff user can access file or "errno" **/
-
- int stat = 0, pid, w;
- * #ifdef BSD
- * union wait status;
- * #else
- * int status;
- * #endif
- register int (*istat)(), (*qstat)();
-
- #ifdef NO_VM /* machine without virtual memory!! */
- if ((pid = fork()) == 0) {
- #else
- if ((pid = vfork()) == 0) {
- #endif
- setuid(userid); /** back to normal userid **/
- setgid(groupid);
- errno = 0;
- * if (access(file, mode))
- * _exit(errno);
- * else
- * _exit(0);
- _exit(127);
- }
-
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
-
- while ((w = wait(&status)) != pid && w != -1)
- ;
-
- * #ifdef BSD
- * if (status.w_retcode != 0) stat = status.w_retcode;
- * #else
- * if (w == -1) stat = status;
- * #endif
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
-
- * return(stat);
- }
- ----------------
- and "can_open()" with;
- ----------------
- int
- can_open(file, mode)
- char *file;
- char *mode;
- {
- /** returns 0 iff user can open the file. This is not
- the same as can_access - it's used for when the file might
- not exist... **/
-
- int stat = 0, pid, w;
- * #ifdef BSD
- * union wait status;
- * #else
- * int status;
- * #endif
- register int (*istat)(), (*qstat)();
-
- #ifdef NO_VM /* machine without virtual memory!! */
- if ((pid = fork()) == 0) {
- #else
- if ((pid = vfork()) == 0) {
- #endif
- setuid(userid); /** back to normal userid **/
- setgid(groupid);
- errno = 0;
- * if (fopen(file, mode) == NULL)
- * _exit(errno);
- * else
- * _exit(0);
- _exit(127);
- }
-
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
-
- while ((w = wait(&status)) != pid && w != -1)
- ;
-
- * #ifdef BSD
- * if (status.w_retcode != 0) stat = status.w_retcode;
- * #else
- * if (w == -1) stat = status;
- * #endif
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
-
- * return(stat);
- }
- --------------
-
- 12. In the file "src/syscall.c" make the following changes;
- Add the following three lines to the top of the file;
- --------------
- #ifdef BSD
- # include <sys/wait.h>
- #endif
- --------------
-
- 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 stat = 0, pid, w;
- * #ifdef BSD
- * union wait status;
- * #else
- * int status;
- * #endif
- 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)
- ;
-
- * #ifdef BSD
- * if (status.w_retcode != 0) stat = status.w_retcode;
- * #else
- * if (w == -1) stat = status;
- * #endif
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
-
- * return(stat);
- }
-
-
- 13. On BSD systems the tgetstr() function seems a tad flaky. This can be
- avoided (to some extent) by changing curses.c as follows;
- --------------
- char *return_value_of(termcap_label)
- char *termcap_label;
- {
- /** This will return the string kept by termcap for the
- specified capability. Modified to ensure that if
- tgetstr returns a pointer to a transient address
- that we won't bomb out with a later segmentation
- fault (thanks to Dave@Infopro for this one!) **/
-
- static char escape_sequence[20];
-
- char *tgetstr(); /* Get termcap capability */
-
- dprint1(9,"return_value_of(%s)\n", termcap_label);
-
- * if (termcap_label[0] == 's' && termcap_label[1] == 'o')
- * strcpy(escape_sequence, _setinverse);
- * else if (termcap_label[0] == 's' && termcap_label[1] == 'e')
- * strcpy(escape_sequence, _clearinverse);
- * else
- strcpy(escape_sequence, tgetstr(termcap_label, &ptr));
-
- return( (char *) escape_sequence);
- }
- --------------
-
- 14. In the file src/newmbox.c, change line 353 to read;
- --------------
- * header_table[count > 0? count-1:count].lines = line + 1;
- --------------
- [The previous version was computing the number of lines in
- the last message in the mailbox incorrectly - this will fix
- that problem]
-
-
-
-
- ENHANCEMENTS
-
- [last added to on 7/11/86]
-
- Enhancement One: support adding user NAMES to outbound mail and replies.
-
- ******************************************************************************
- * NOTE: You'll need Enhancement two to be able to fully utilize this *
- * feature - this set of changes will allow sending and replying *
- * INDIVIDUALLY to users with their names on the outbound addresses *
- * It will NOT be able to deal with G)roup replies until the next *
- * BUGFIX document is issued. Install at your own risk (as always) *
- ******************************************************************************
-
- 1. Replace the file "utils/newalias.c" with the following file (lots of
- changes...)
-
- [the following is 511 lines long...]
- ----------------------
- /** newalias.c **/
-
- /** (C) Copyright 1986 Dave Taylor **/
-
- /** Install a new set of aliases for the 'Elm' mailer.
-
- If invoked with a specific filename, it assumes that
- it is working with an individual users alias tables, and
- generates the .alias.hash and .alias.data files in their
- home directory.
- If, however, it is invoked with no arguments, then
- it assumes that the user is updating the system alias
- file and uses the defaults for everything.
-
- The format for the input file is;
- alias1, alias2, ... : username : address
- or alias1, alias2, ... : groupname: member, member, member, ...
- member, member, member, ...
-
- "-q" flag added: 6/17/86
- **/
-
- #ifdef BSD
- # include <sys/file.h>
- #else
- # include <fcntl.h>
- #endif
-
- #include <stdio.h>
- #include "defs.h" /* ELM system definitions */
-
- static char ident[] = { WHAT_STRING };
-
- #ifndef TAB
- # define TAB '\t' /* TAB character! */
- #endif
-
- #define alias_hash ".alias_hash"
- #define alias_data ".alias_data"
- #define alias_text ".alias_text"
-
- #define group(string) (strpbrk(string,", ") != NULL)
-
- struct alias_rec
- shash_table[MAX_SALIASES]; /* the actual hash table */
-
- struct alias_rec
- uhash_table[MAX_UALIASES]; /* the actual hash table */
-
- int hash_table_loaded=0; /* is system table actually loaded? */
-
- int buff_loaded; /* for file input overlap... */
- int error= 0; /* if errors, don't save! */
- int system=0; /* system file updating? */
- int count=0; /* how many aliases so far? */
- long offset = 0L; /* data file line offset! */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *in, *data;
- char inputname[SLEN], hashname[SLEN], dataname[SLEN];
- char home[SLEN], buffer[LONG_STRING];
- int hash, count = 0, owner, quiet = 0;
-
- if (argc != 1)
- if (strcmp(argv[1], "-q") == 0)
- quiet++;
- else
- exit(printf("Usage: %s\n", argv[0]));
-
- owner = getuid();
-
- if (owner == 0 && ! quiet) { /* being run by root! */
- printf("Would you like to update the system aliases? (y/n)");
- gets(buffer, 2);
- if (buffer[0] == 'y' || buffer[0] == 'Y') {
- printf("Updating the system alias file...\n");
-
- sprintf(inputname, "%s/%s", mailhome, alias_text);
- sprintf(hashname, "%s/%s", mailhome, alias_hash);
- sprintf(dataname, "%s/%s", mailhome, alias_data);
- system++;
- init_table(shash_table, MAX_SALIASES);
- }
- else
- printf("Updating your personal alias file...\n");
- }
-
- if (! system) {
- if (strcpy(home, getenv("HOME")) == NULL)
- exit(printf("Confused: No HOME variable in environment!\n"));
-
- sprintf(inputname, "%s/%s", home, alias_text);
- sprintf(hashname, "%s/%s", home, alias_hash);
- sprintf(dataname, "%s/%s", home, alias_data);
-
- init_table(uhash_table, MAX_UALIASES);
-
- read_in_system(shash_table, sizeof shash_table);
- }
-
- if ((in = fopen(inputname,"r")) == NULL)
- exit(printf("Couldn't open %s for input!\n", inputname));
-
- if ((hash = open(hashname, O_WRONLY | O_CREAT, 0644)) == -1)
- exit(printf("Couldn't open %s for output!\n", hashname));
-
- if ((data = fopen(dataname,"w")) == NULL)
- exit(printf("Couldn't open %s for output!\n", dataname));
-
- buff_loaded = 0; /* file buffer empty right now! */
-
- while (get_alias(in, buffer) != -1) {
- if (system)
- put_alias(data, buffer, shash_table, MAX_SALIASES);
- else
- put_alias(data, buffer, uhash_table, MAX_UALIASES);
- count++;
- }
-
- if (error) {
- printf("\n** Not saving tables! Please fix and re-run %s!\n",
- argv[0]);
- exit(1);
- }
- else {
- if (system)
- write(hash, shash_table, sizeof shash_table);
- else
- write(hash, uhash_table, sizeof uhash_table);
-
- close(hash);
- fclose(data);
- close(in);
-
- printf("Processed %d aliases\n", count);
- exit(0);
- }
- }
-
- int
- get_alias(file, buffer)
- FILE *file;
- char *buffer;
- {
- /* load buffer with the next complete alias from the file.
- (this can include reading in multiple lines and appending
- them all together!) Returns EOF after last entry in file.
-
- Lines that start with '#' are assumed to be comments and are
- ignored. White space as the first field of a line is taken
- to indicate that this line is a continuation of the previous. */
-
- static char mybuffer[SLEN];
- int done = 0, first_read = 1;
-
- /** get the first line of the entry... **/
-
- buffer[0] = '\0'; /* zero out line */
-
- do {
- if (get_line(file, mybuffer, first_read) == -1)
- return(-1);
- first_read = 0;
- if (mybuffer[0] != '#')
- strcpy(buffer, mybuffer);
- } while (strlen(buffer) == 0);
-
- /** now read in the rest (if there is any!) **/
-
- do {
- if (get_line(file, mybuffer, first_read) == -1) {
- buff_loaded = 0; /* force a read next pass! */
- return(0); /* okay. let's just hand 'buffer' back! */
- }
- done = (mybuffer[0] != ' ' && mybuffer[0] != TAB);
- if (mybuffer[0] != '#' && ! done)
- strcat(buffer, mybuffer);
- done = (done && mybuffer[0] != '#');
- } while (! done);
-
- return(0); /* no sweat! */
- }
-
- put_alias(data, buffer, table, size)
- FILE *data;
- char *buffer;
- struct alias_rec table[];
- int size;
- {
- /** break buffer down into three pieces: aliases, comment, and address.
- Make the appropriate entries in the table (size)
- **/
-
- char aliases[LONG_STRING], address[LONG_STRING];
- char comment[LONG_STRING];
- int first, last, i = 0, j = 0;
-
- remove_all(' ', TAB, buffer);
-
- for (i=0; buffer[i] != ':' && i < LONG_STRING; i++)
- aliases[i] = buffer[i];
- aliases[i] = '\0';
-
- for (i=strlen(buffer)-1; buffer[i] != ':' && i > 0; i--)
- address[j++] = buffer[i];
- address[j] = '\0';
-
- comment[0] = '\0'; /* default to nothing at all... */
-
- if ((first=strlen(aliases)+1) < (last=(strlen(buffer) - j))) {
- extract_comment(comment, buffer, first, last);
- }
-
- reverse(address);
-
- add_to_table(data, aliases, comment, address, table, size);
- }
-
- int
- get_line(file, buffer, first_line)
- FILE *file;
- char *buffer;
- int first_line;
- {
- /** read line from file. If first_line and buff_loaded,
- then just return! **/
- int stat;
-
- if (first_line && buff_loaded) {
- buff_loaded = 1;
- return;
- }
-
- buff_loaded = 1; /* we're going to get SOMETHING in the buffer */
-
- stat = fgets(buffer, SLEN, file) == NULL ? -1 : 0;
-
- if (stat != -1)
- no_ret(buffer);
-
- return(stat);
- }
-
- reverse(string)
- char *string;
- {
- /** reverse the order of the characters in string...
- uses a bubble-sort type of algorithm! **/
-
- register int f, l;
- char c;
-
- f = 0;
- l = strlen(string) - 1;
-
- while (f < l) {
- c = string[f];
- string[f] = string[l];
- string[l] = c;
- f++;
- l--;
- }
- }
-
- add_to_table(data, aliases, comment, address, table, size)
- FILE *data;
- char *aliases, *comment, *address;
- struct alias_rec table[];
- int size;
- {
- /** add address + comment to datafile, incrementing offset count
- (bytes), then for each alias in the aliases string, add to the
- hash table, with the associated pointer value! **/
-
- static char buf[SLEN], *word;
- long additive = 1L;
-
- word = buf; /* use the allocated space! */
-
- if (group(address)) {
- check_group(address, aliases);
- if (error) return; /* don't do work if we aren't to save it! */
- fprintf(data, "!%s\n", address);
- additive = 2L;
- }
- else {
- if (error) return; /* don't do work if we aren't to save it! */
- if (strlen(comment) > 0) {
- fprintf(data, "%s (%s)\n", address, comment);
- additive = (long) (strlen(comment) + 4);
- }
- else
- fprintf(data, "%s\n", address, comment);
- }
-
- while ((word = (char *) strtok(aliases,", ")) != NULL) {
- add_to_hash_table(word, offset, table, size);
- aliases = NULL; /* let's get ALL entries via 'strtok' */
- count++;
- }
-
- if ( system ? count > MAX_SALIASES-35 : count > MAX_UALIASES-21) {
- printf("** Too many aliases in file! **\n");
- error++;
- }
-
- offset = (offset + (long) strlen(address) + additive);
- }
-
- remove_all(c1, c2, string)
- char c1, c2, *string;
- {
- /* Remove all occurances of character 'c1' or 'c2' from the string.
- Hacked (literally) to NOT remove ANY characters from within the
- colon fields. This will only be used if the line contains TWO
- colons (and comments with colons in them are the kiss of death!)
- */
-
- char buffer[LONG_STRING];
- register int i = 0, j = 0, first_colon = -1, last_colon = -1;
-
- for (i = 0; string[i] != '\0' && i < LONG_STRING; i++) {
- if (string[i] != c1 && string[i] != c2)
- buffer[j++] = string[i];
-
- if (first_colon == -1 && string[i] == ':') {
- first_colon = i;
- for (last_colon=strlen(string);string[last_colon] != ':';
- last_colon--) ;
- }
- else if (i > first_colon && i < last_colon)
- if (string[i] == c1 || string[i] == c2)
- buffer[j++] = string[i];
- }
-
- buffer[j] = '\0';
- strcpy(string, buffer);
- }
-
- add_to_hash_table(word, offset, table, size)
- char *word;
- long offset;
- struct alias_rec table[];
- int size;
- {
- /** add word and offset to current hash table. **/
- register int loc;
-
- if (strlen(word) > 20)
- exit(printf("Bad alias name: %s. Too long.\n", word));
-
- loc = hash_it(word, size);
-
- while (table[loc].name[0] != '\0' && strcmp(table[loc].name, word) != 0)
- loc = loc + 1 % size;
-
- if (table[loc].name[0] == '\0') {
- strcpy(table[loc].name, word);
- table[loc].byte = offset;
- }
- else
- printf("** Duplicate alias '%s' in file. Multiples ignored.\n",
- word);
- }
-
- int
- hash_it(string, table_size)
- char *string;
- {
- /** 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);
- }
-
- init_table(table, size)
- struct alias_rec table[];
- int size;
- {
- /** initialize hash table! **/
-
- register int i;
-
- for (i=0; i < size; i++)
- table[i].name[0] = '\0';
- }
-
- read_in_system(table, size)
- struct alias_rec table[];
- int size;
- {
- /** read in the system hash table...to check for group aliases
- from the user alias file (to ensure that there are no names
- in the user group files that are not purely contained within
- either alias table) **/
-
- int fd;
- char fname[SLEN];
-
- sprintf(fname, "%s/%s", mailhome, alias_hash);
-
- if ((fd = open(fname, O_RDONLY)) == -1)
- return; /* no sweat: flag 'hash_table_loaded' not set! */
-
- (void) read(fd, table, size);
- close(fd);
- hash_table_loaded++;
- }
-
- check_group(names, groupname)
- char *names, *groupname;
- {
- /** one by one make sure each name in the group is defined
- in either the system alias file or the user alias file.
- This search is linearly dependent, so all group aliases
- in the source file should appear LAST, after all the user
- aliases! **/
-
- char *word, *bufptr, buffer[LONG_STRING];
-
- strcpy(buffer, names);
- bufptr = (char *) buffer;
-
- while ((word = (char *) strtok(bufptr,", ")) != NULL) {
- if (! can_find(word))
- if (! valid_name(word)) {
- error++;
- printf("** Alias %s in group %s is bad!\n", word, groupname);
- }
- bufptr = NULL;
- }
- }
-
- int
- can_find(name)
- char *name;
- {
- /** find name in either hash table...use 'system' variable to
- determine if we should look in both or just system.... **/
-
- register int loc;
-
- if (strlen(name) > 20) {
- error++;
- printf("** Bad alias name: %s. Too long.\n", name);
- return(1); /* fake out: don't want 2 error messages! */
- }
-
- /** system alias table... **/
- if (hash_table_loaded || system) {
- loc = hash_it(name, MAX_SALIASES);
-
- while (strcmp(name, shash_table[loc].name) != 0 &&
- shash_table[loc].name[0] != '\0')
- loc = (loc + 1) % MAX_SALIASES;
-
- if (strcmp(name, shash_table[loc].name) == 0)
- return(1); /* found it! */
- }
-
- if (! system) { /* okay! Let's check the user alias file! */
- loc = hash_it(name, MAX_UALIASES);
-
- while (strcmp(name, uhash_table[loc].name) != 0 &&
- uhash_table[loc].name[0] != '\0')
- loc = (loc + 1) % MAX_UALIASES;
-
- if (strcmp(name, uhash_table[loc].name) == 0)
- return(1); /* found it! */
- }
-
- return(0);
- }
-
- extract_comment(comment, buffer, first, last)
- char *comment, *buffer;
- int first, last;
- {
- /** Buffer contains a comment, located between the first and last
- values. Copy that into 'comment', but remove leading and
- trailing white space.
- **/
-
- register int loc = 0;
-
- /** first off, skip the LEADING white space... **/
-
- while (buffer[first] == ' ') first++;
-
- /** now let's backup the 'last' value until we hit a non-space **/
-
- last -= 2; /* starts at ch AFTER colon.. */
- while (buffer[last] == ' ') last--;
-
- /** now a final check to make sure we're still talking about a
- reasonable string (rather than a "joe :: joe@dec" type string) **/
-
- if (first < last) {
- while (first <= last)
- comment[loc++] = buffer[first++];
- comment[loc] = '\0';
- }
- }
- ----------------------
- [end of utils/newalias.c]
-
- 2. The next step is to go into the file "src/mailmsg2.c" and change the
- file to reflect;
-
- [approx. at line 180]
- -------------
- sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
- * mailx, subject, strip_parens(strip_commas(expanded_to)),
- remove, filename, filename);
-
- -------------
- sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s",
- * sendmail, smflags, strip_parens(strip_commas(expanded_to)),
- remove, filename2, filename2);
- else /* oh well, use default mailer... */
- sprintf(very_long_buffer,"( (%s %s ; %s %s) & ) < %s",
- * mailer, strip_parens(strip_commas(expanded_to)),
- remove, filename2, filename2);
- -------------
- [the change is the nested call to "strip_parens()" when cleaning up the
- 'to' address list...]
-
- 3. Finally, in src/return_addr.c, change the last few lines of the
- routine "get_return" to;
- ------------
- 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);
- * else {
- * if (chloc(' ', header_table[current-1].from) > -1 ||
- * (chloc('!', header_table[current-1].from) < 0 &&
- * chloc('@', header_table[current-1].from) < 0))
- * sprintf(name2, " (%s)", header_table[current-1].from);
- * strcat(buffer, name2);
- * }
- }
- -------------
-
- --- end of attachment
-
-