rsalz@uunet.uu.net (Rich Salz) (04/14/89)
Submitted-by: dsinc!syd@uunet.UU.NET (Syd Weinstein) Posting-number: Volume 18, Issue 102 Archive-name: elm2.2/part23 #!/bin/sh # this is part 23 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file utils/arepdaem.c continued # CurArch=23 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/arepdaem.c" sed 's/^X//' << 'SHAR_EOF' >> utils/arepdaem.c 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 Xreply_to_mail(person, from, subject) Xint person; Xchar *from, *subject; X{ X /** Respond to the message from the specified person with the X specified subject... **/ X X char buffer[SLEN]; X X if (strlen(subject) == 0) X strcpy(subject, "Auto-reply Mail"); X else if (! first_word(subject,"Auto-reply")) { X sprintf(buffer, "Auto-reply to:%s", subject); X strcpy(subject, buffer); X } X X log("auto-replying to '%s'", from); X X mail(from, subject, reply_table[person].replyfile, person); 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 unlock(); X exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name)); X } X else X ok = 0; X X return(ok ? buffer.st_size : 0); X} X Xmail(to, subject, filename, person) Xchar *to, *subject, *filename; Xint person; X{ X /** Mail 'file' to the user from person... **/ X X char buffer[VERY_LONG_STRING]; X X sprintf(buffer, "%s -f '%s [autoreply]' -s '%s' %s %s", X fastmail, reply_table[person].username, X subject, filename, to); X X system(buffer); X} X Xlog(message, arg) Xchar *message; Xchar *arg; X{ X /** Put log entry into log file. Use the format: X date-time: <message> X **/ X X struct tm *localtime(), *thetime; X long time(), clock; X char buffer[SLEN]; X X /** first off, get the time and date **/ X X clock = time((long *) 0); /* seconds since ??? */ X thetime = localtime(&clock); /* and NOW the time... */ X X /** then put the message out! **/ X X sprintf(buffer, message, arg); X X fprintf(logfd,"%d/%d-%d:%02d: %s\n", X thetime->tm_mon+1, thetime->tm_mday, X thetime->tm_hour, thetime->tm_min, X buffer); X} X XFILE *open_logfile() X{ X /** open the logfile. returns a valid file descriptor **/ X X FILE *fd; X X if ((fd = fopen(logfile, "a")) == NULL) X if ((fd = fopen(logfile2, "a")) == NULL) { X unlock(); X exit(1); /* give up! */ X } X X return( (FILE *) fd); X} X Xclose_logfile() X{ X /** Close the logfile until needed again. **/ X X fclose(logfd); X} X Xchar *strip_parens(string) Xchar *string; X{ X /** Return string with all parenthesized information removed. X This is a non-destructive algorithm... **/ X X static char buffer[SLEN]; X register int i, depth = 0, buffer_index = 0; X X for (i=0; i < strlen(string); i++) { X if (string[i] == '(') X depth++; X else if (string[i] == ')') X depth--; X else if (depth == 0) X buffer[buffer_index++] = string[i]; X } X X buffer[buffer_index] = '\0'; X X return( (char *) buffer); X} X X/*** LOCK and UNLOCK - ensure only one copy of this daemon running at any X given time by using a file existance semaphore (wonderful stuff!) ***/ X Xlock() X{ X /** Try to create the lock file. If it's there, or we can't X create it for some stupid reason, return zero, otherwise, X a non-zero return code indicates success in locking this X process in. **/ X X if (access(arep_lock_file, EXISTS) == 0) X return(0); /* file already exists!! */ X X if (creat(arep_lock_file, MODE) == -1) X return(0); /* can't create file!! */ X X return(1); X} X Xunlock() X{ X /** remove lock file if it's there! **/ X X (void) unlink(arep_lock_file); X} SHAR_EOF echo "File utils/arepdaem.c is complete" chmod 0444 utils/arepdaem.c || echo "restore of utils/arepdaem.c fails" echo "x - extracting utils/autoreply.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/autoreply.c && X Xstatic char rcsid[] = "@(#)$Id: autoreply.c,v 2.3 89/03/25 21:47:41 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.3 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: autoreply.c,v $ X * Revision 2.3 89/03/25 21:47:41 syd X * Initial 2.2 Release checkin X * X * X ******************************************************************************/ X X/** This is the front-end for the autoreply system, and performs two X functions: it either adds the user to the list of people using the X autoreply function (starting the daemon if no-one else) or removes X a user from the list of people. X X Usage: autoreply filename X autoreply "off" X or autoreply [to find current status] 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 Xstatic char ident[] = { WHAT_STRING }; X X#define tempdir "/tmp/arep" /* file prefix */ X#define autoreply_file "/etc/autoreply.data" /* autoreply data file */ X Xextern int errno; /* system error code */ Xchar username[NLEN]; /* login name of user */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X char filename[SLEN]; X X if (argc > 2) { X printf("Usage: %s <filename>\tto start autoreply,\n", argv[0]); X printf(" %s off\t\tto turn off autoreply\n", argv[0]); X printf(" or %s \t\tto check current status\n", argv[0]); X exit(1); X } X X (void) cuserid(username); X X if (argc == 1 || strcmp(argv[1], "off") == 0) X remove_user((argc == 1)); X else { X strcpy(filename, argv[1]); X if (access(filename,READ_ACCESS) != 0) { X printf("Error: Can't read file '%s'\n", filename); X exit(1); X } X X if (filename[0] != '/') /* prefix home directory */ X sprintf(filename,"%s/%s", getenv("HOME"), argv[1]); X X add_user(filename); X } X X exit(0); X} X Xremove_user(stat_only) Xint stat_only; X{ X /** Remove the user from the list of currently active autoreply X people. If 'stat_only' is set, then just list the name of X the file being used to autoreply with, if any. **/ X X FILE *temp, *repfile; X char tempfile[SLEN], user[SLEN], filename[SLEN]; X int c, copied = 0, found = 0; X long filesize, bytes(); X X if (! stat_only) { X sprintf(tempfile, "%s.%06d", tempdir, getpid()); X X if ((temp = fopen(tempfile, "w")) == NULL) { X printf("Error: couldn't open tempfile '%s'. Not removed\n", X tempfile); X exit(1); X } X } X X if ((repfile = fopen(autoreply_file, "r")) == NULL) { X if (stat_only) { X printf("You're not currently autoreplying to mail.\n"); X exit(0); X } X printf("No-one is autoreplying to their mail!\n"); X exit(0); X } X X /** copy out of real replyfile... **/ X X while (fscanf(repfile, "%s %s %ld", user, filename, &filesize) != EOF) X X if (strcmp(user, username) != 0) { X if (! stat_only) { X copied++; X fprintf(temp, "%s %s %ld\n", user, filename, filesize); X } X } X else { X if (stat_only) { X printf("You're currently autoreplying to mail with the file %s\n", filename); X exit(0); X } X found++; X } X X fclose(temp); X fclose(repfile); X X if (! found) { X printf("You're not currently autoreplying to mail%s\n", X stat_only? "." : "!"); X if (! stat_only) X unlink(tempfile); X exit(! stat_only); X } X X /** now copy tempfile back into replyfile **/ X X if (copied == 0) { /* removed the only person! */ X unlink(autoreply_file); X } X else { /* save everyone else */ X X if ((temp = fopen(tempfile,"r")) == NULL) { X printf("Error: couldn't reopen tempfile '%s'. Not removed.\n", X tempfile); X unlink(tempfile); X exit(1); X } X X if ((repfile = fopen(autoreply_file, "w")) == NULL) { X printf( X "Error: couldn't reopen autoreply file for writing! Not removed.\n"); X unlink(tempfile); X exit(1); X } X X while ((c = getc(temp)) != EOF) X putc(c, repfile); X X fclose(temp); X fclose(repfile); X X } X unlink(tempfile); X X if (found > 1) X printf("Warning: your username appeared %d times!! Removed all\n", X found); X else X printf("You've been removed from the autoreply table.\n"); X} X Xadd_user(filename) Xchar *filename; X{ X /** add the user to the autoreply file... **/ X X FILE *repfile; X char mailfile[SLEN]; X long bytes(); X X if ((repfile = fopen(autoreply_file, "a")) == NULL) { X printf("Error: couldn't open the autoreply file! Not added\n"); X exit(1); X } X X sprintf(mailfile,"%s/%s", mailhome, username); X X fprintf(repfile,"%s %s %ld\n", username, filename, bytes(mailfile)); X X fclose(repfile); X X printf("You've been added to the autoreply system.\n"); X} 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 exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name)); X else X ok = 0; X X return(ok ? buffer.st_size : 0L); X} SHAR_EOF chmod 0444 utils/autoreply.c || echo "restore of utils/autoreply.c fails" echo "x - extracting utils/checkalias (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/checkalias && X: Use /bin/sh X# checkalias: part of the Elm mail system X# @(#)$Id: checkalias,v 2.1 89/03/03 17:46:56 syd Exp $ X Xif [ "$*" = "" ]; then X echo Usage: checkalias alias \[alias ...\] 1>&2 X exit 1 Xfi X Xexec elm -c $* SHAR_EOF chmod 0444 utils/checkalias || echo "restore of utils/checkalias fails" echo "x - extracting utils/expand.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/expand.c && X Xstatic char rcsid[] = "@(#)$Id: expand.c,v 2.3 89/03/25 21:47:43 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.3 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: expand.c,v $ X * Revision 2.3 89/03/25 21:47:43 syd X * Initial 2.2 Release checkin X * X * X ******************************************************************************/ X X/** This is a library routine for the various utilities that allows X users to have the standard 'Elm' folder directory nomenclature X for all filenames (e.g. '+', '=' or '%'). It should be compiled X and then linked in as needed. X X**/ X X#include <stdio.h> X#include "defs.h" X Xchar *expand_define(); X Xint Xexpand(filename) Xchar *filename; X{ X /** Expand the filename since the first character is a meta- X character that should expand to the "maildir" variable X in the users ".elmrc" file... X X Note: this is a brute force way of getting the entry out X of the .elmrc file, and isn't recommended for the faint X of heart! X **/ X X FILE *rcfile; X char buffer[SLEN], *expanded_dir, *home, *getenv(), *bufptr; X int foundit = 0; X X bufptr = (char *) buffer; /* same address */ X X if ((home = getenv("HOME")) == NULL) { X printf( X "Can't expand environment variable $HOME to find .elmrc file!\n"); X exit(1); X } X X sprintf(buffer, "%s/%s", home, elmrcfile); X X if ((rcfile = fopen(buffer, "r")) == NULL) { X printf("Can't open your \".elmrc\" file (%s) for reading!\n", X buffer); X exit(1); X } X X while (fgets(buffer, SLEN, rcfile) != NULL && ! foundit) { X if (strncmp(buffer, "maildir", 7) == 0 || X strncmp(buffer, "folders", 7) == 0) { X while (*bufptr != '=' && *bufptr) X bufptr++; X bufptr++; /* skip the equals sign */ X while (whitespace(*bufptr) && *bufptr) X bufptr++; X home = bufptr; /* remember this address */ X X while (! whitespace(*bufptr) && *bufptr != '\n') X bufptr++; X X *bufptr = '\0'; /* remove trailing space */ X foundit++; X } X } X X fclose(rcfile); /* be nice... */ X X if (! foundit) { X printf("Couldn't find \"maildir\" in your .elmrc file!\n"); X exit(1); X } X X /** Home now points to the string containing your maildir, with X no leading or trailing white space... X **/ X X expanded_dir = expand_define(home); X X sprintf(buffer, "%s%s%s", expanded_dir, X (expanded_dir[strlen(expanded_dir)-1] == '/' || X filename[0] == '/') ? "" : "/", (char *) filename+1); X X strcpy(filename, buffer); X} X Xchar *expand_define(maildir) Xchar *maildir; X{ X /** This routine expands any occurances of "~" or "$var" in X the users definition of their maildir directory out of X their .elmrc file. X X Again, another routine not for the weak of heart or staunch X of will! X **/ X X static char buffer[SLEN]; /* static buffer AIEE!! */ X char name[SLEN], /* dynamic buffer!! (?) */ X *nameptr, /* pointer to name?? */ X *value; /* char pointer for munging */ X X if (*maildir == '~') X sprintf(buffer, "%s%s", getenv("HOME"), ++maildir); X else if (*maildir == '$') { /* shell variable */ X X /** break it into a single word - the variable name **/ X X strcpy(name, (char *) maildir + 1); /* hurl the '$' */ X nameptr = (char *) name; X while (*nameptr != '/' && *nameptr) nameptr++; X *nameptr = '\0'; /* null terminate */ X X /** got word "name" for expansion **/ X X if ((value = getenv(name)) == NULL) { X printf("Couldn't expand shell variable $%s in .elmrc!\n", name); X exit(1); X } X sprintf(buffer, "%s%s", value, maildir + strlen(name) + 1); X } X else strcpy(buffer, maildir); X X return( ( char *) buffer); X} SHAR_EOF chmod 0444 utils/expand.c || echo "restore of utils/expand.c fails" echo "x - extracting utils/fastmail.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/fastmail.c && X Xstatic char rcsid[] = "@(#)$Id: fastmail.c,v 2.5 89/03/25 21:47:44 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.5 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: fastmail.c,v $ X * Revision 2.5 89/03/25 21:47:44 syd X * Initial 2.2 Release checkin X * X * X ******************************************************************************/ X X/** This program is specifically written for group mailing lists and X such batch type mail processing. It does NOT use aliases at all, X it does NOT read the /etc/password file to find the From: name X of the user and does NOT expand any addresses. It is meant X purely as a front-end for either /bin/mail or /usr/lib/sendmail X (according to what is available on the current system). X X **** This program should be used with CAUTION ***** X X**/ X X/** The calling sequence for this program is: X X fastmail {args} filename full-email-address X X where args could be any (or all) of; X X -b bcc-list (Blind carbon copies to) X -c cc-list (carbon copies to) X -d (debug on) X -f from (from name) X -F from-addr (the actual address to be put in the From: line) X -r reply-to-address (Reply-To:) X -s subject (subject of message) X**/ X X#include <stdio.h> X#include "defs.h" X#include "patchlevel.h" X X#ifdef BSD X# ifdef TMINSYS X# include <sys/time.h> X# else X# include <time.h> X# include <sys/types.h> X# include <sys/timeb.h> X# endif X#else X# include <time.h> X#endif X Xstatic char ident[] = { WHAT_STRING }; X X#define binrmail "/bin/rmail" X#define temphome "/tmp/fastmail." X X Xchar *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu", X "Fri", "Sat", "" }; X Xchar *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""}; X Xchar *get_arpa_date(); X X#ifdef BSD X char *timezone(); X#else X extern char *tzname[]; X#endif X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X X extern char *optarg; X extern int optind; X FILE *tempfile; X char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN]; X char filename[SLEN], tempfilename[SLEN], command_buffer[256]; X char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN]; X char from_addr[SLEN]; X int c, sendmail_available, debug = 0; X X subject[0] = '\0'; X replyto[0] = '\0'; X cc_list[0] = '\0'; X bcc_list[0] = '\0'; X from_addr[0] = '\0'; X X while ((c = getopt(argc, argv, "b:c:df:F:r:s:")) != EOF) { X switch (c) { X case 'b' : strcpy(bcc_list, optarg); break; X case 'c' : strcpy(cc_list, optarg); break; X case 'd' : debug++; break; X case 'f' : strcpy(from_string, optarg); break; X case 'F' : strcpy(from_addr, optarg); break; X case 'r' : strcpy(replyto, optarg); break; X case 's' : strcpy(subject, optarg); break; X case '?' : X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n"); X fprintf(stderr,"\t-f from-name\n\t-F from-addr\n"); X fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X } X X if (optind > argc) { X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n"); X fprintf(stderr,"\t-F from-addr\n"); X fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X X strcpy(filename, argv[optind++]); X X if (optind > argc) { X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n"); X fprintf(stderr,"\t-F from-addr\n"); X fprintf(stderr,"\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X X#ifdef HOSTCOMPILED X strncpy(hostname, HOSTNAME, sizeof(hostname)); X#else X gethostname(hostname, sizeof(hostname)); X#endif X X strcpy(username, getlogin()); X X if (strlen(username) == 0) X cuserid(username); X X if (access(filename, READ_ACCESS) == -1) X exit(fprintf(stderr, "Error: can't find file %s!\n", filename)); X X sprintf(tempfilename, "%s%d", temphome, getpid()); X X if ((tempfile = fopen(tempfilename, "w")) == NULL) X exit(fprintf(stderr, "Couldn't open temp file %s\n", tempfilename)); X X /** Subject must appear even if "null" and must be first X at top of headers for mail because the X pure System V.3 mailer, in its infinite wisdom, now X assumes that anything the user sends is part of the X message body unless either: X 1. the "-s" flag is used (although it doesn't seem X to be supported on all implementations??) X 2. the first line is "Subject:". If so, then it'll X read until a blank line and assume all are meant X to be headers. X So the gory solution here is to move the Subject: line X up to the top. I assume it won't break anyone elses program X or anything anyway (besides, RFC-822 specifies that the *order* X of headers is irrelevant). Gahhhhh.... X **/ X fprintf(tempfile, "Subject: %s\n", subject); X X if (strlen(from_string) > 0) X if (strlen(from_addr) > 0) X fprintf(tempfile, "From: %s (%s)\n", from_addr, from_string); X else X fprintf(tempfile, "From: %s!%s (%s)\n", hostname, username, X from_string); X else X if (strlen(from_addr) > 0) X fprintf(tempfile, "From: %s\n", from_addr); X else X fprintf(tempfile, "From: %s!%s\n", hostname, username); X X fprintf(tempfile, "Date: %s\n", get_arpa_date()); X X if (strlen(replyto) > 0) X fprintf(tempfile, "Reply-To: %s\n", replyto); X X while (optind < argc) X sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? " ":""), X argv[optind++]); X X fprintf(tempfile, "To: %s\n", to_list); X X if (strlen(cc_list) > 0) X fprintf(tempfile, "Cc: %s\n", cc_list); X X fprintf(tempfile, "X-Mailer: fastmail [version %s PL%d]\n", X VERSION, PATCHLEVEL); X fprintf(tempfile, "\n"); X X fclose(tempfile); X X /** now we'll cat both files to /bin/rmail or sendmail... **/ X X sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1); X X printf("Mailing to %s%s%s%s%s [via %s]\n", to_list, X (strlen(cc_list) > 0 ? " ":""), cc_list, X (strlen(bcc_list) > 0 ? " ":""), bcc_list, X sendmail_available? "sendmail" : "rmail"); X X sprintf(command_buffer, "cat %s %s | %s %s %s %s", X tempfilename, filename, X sendmail_available? sendmail : mailer, X to_list, cc_list, bcc_list); X X if (debug) X printf("%s\n", command_buffer); X X system(command_buffer); X X unlink(tempfilename); X} X X Xchar *get_arpa_date() X{ X /** returns an ARPA standard date. The format for the date X according to DARPA document RFC-822 is exemplified by; X X Mon, 12 Aug 85 6:29:08 MST X X **/ X X static char buffer[SLEN]; /* static character buffer */ X struct tm *the_time, /* Time structure, see CTIME(3C) */ X *localtime(); X long junk; /* time in seconds.... */ X#ifdef BSD X# ifndef TMINSYS X struct timeb loc_time; /* of course this is different! */ X# else X struct timeval time_val; X struct timezone time_zone; X# endif X#endif X X#ifdef BSD X# ifndef TMINSYS X junk = (long) time((long *) 0); X ftime(&loc_time); X# else X gettimeofday(&time_val, &time_zone); X junk = time_val.tv_sec; X# endif X#else X junk = time(0); /* this must be here for it to work! */ X#endif X the_time = localtime(&junk); X X sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s", X arpa_dayname[the_time->tm_wday], X the_time->tm_mday % 32, X arpa_monname[the_time->tm_mon], X the_time->tm_year % 100, X the_time->tm_hour % 24, X the_time->tm_min % 61, X the_time->tm_sec % 61, X#ifdef BSD X# ifndef TMINSYS X timezone(loc_time.time_zone, the_time->tz_isdst)); X# else X timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime)); X# endif X#else X tzname[the_time->tm_isdst]); X#endif X X return( (char *) buffer); X} SHAR_EOF chmod 0444 utils/fastmail.c || echo "restore of utils/fastmail.c fails" echo "x - extracting utils/from.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/from.c && X Xstatic char rcsid[] = "@(#)$Id: from.c,v 2.9 89/03/25 21:47:46 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.9 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: from.c,v $ X * Revision 2.9 89/03/25 21:47:46 syd X * Initial 2.2 Release checkin X * X * X ******************************************************************************/ X X/** print out whom each message is from in the pending folder or specified X one, including a subject line if available.. X X**/ X X#include <stdio.h> X#include <pwd.h> X#include "defs.h" X Xstatic char ident[] = { WHAT_STRING }; X X#define LINEFEED (char) 10 X X#define metachar(c) (c == '=' || c == '+' || c == '%') X XFILE *mailfile; X Xchar *expand_define(); Xint number = 0, /* should we number the messages?? */ X verbose = 0; /* and should we prepend a header? */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X char infile[SLEN], *cp ; X int multiple_files = 0, output_files = 0, c; X struct passwd *pass, *getpwuid(); X X extern int optind; X X while ((c = getopt(argc, argv, "nv")) != EOF) X switch (c) { X case (int)'n': number++; break; X case (int)'v': verbose++; break; X case (int)'?': printf("Usage: %s [-n] [-v] {filename | username}\n", X argv[0]); X exit(1); X } X X infile[0] = '\0'; X if (optind == argc) { X /* X * determine mail file from environment variable if found, X * else use password entry X */ X if ((cp = getenv("MAIL")) == NULL) { X if((pass = getpwuid(getuid())) == NULL) { X printf("You have no password entry!"); X exit(1); X } X sprintf(infile,"%s%s",mailhome, pass->pw_name); X } X else X strcpy(infile, cp); X optind -= 1; /* ensure one pass through loop */ X } X X multiple_files = (argc - optind > 1); X X while (optind < argc) { X X if (multiple_files) { X strcpy(infile, argv[optind]); X printf("%s%s: \n", output_files++ > 0 ? "\n":"", infile); X } X else if (infile[0] == '\0') X strcpy(infile, argv[optind]); X X if (metachar(infile[0])) { X if (expand(infile) == 0) { X fprintf(stderr, "%s: couldn't expand filename %s!\n", X argv[0], infile); X exit(1); X } X } X X if ((mailfile = fopen(infile,"r")) == NULL) { X if (optind+1 == argc) X printf("No mail.\n"); X else { X if (infile[0] == '/') X printf("Couldn't open folder \"%s\".\n", infile); X else { X sprintf(infile,"%s%s", mailhome, argv[optind]); X if ((mailfile = fopen(infile,"r")) == NULL) X printf("Couldn't open folders \"%s\" or \"%s\".\n", X argv[optind], infile); X else if (read_headers()==0) X printf("No messages in that folder!\n"); X } X } X } X else X if (read_headers(optind+1 == argc)==0) X if (optind+1 == argc) X printf("No mail\n"); X else X printf("No messages in that folder!\n"); X X optind++; X } X exit(0); X} X Xint Xread_headers(user_mailbox) Xint user_mailbox; X{ X /** Read the headers, output as found. User-Mailbox is to guarantee X that we get a reasonably sensible message from the '-v' option X **/ X X char buffer[SLEN], from_whom[SLEN], subject[SLEN]; X register int subj = 0, in_header = 0, count = 0; X X while (fgets(buffer, SLEN, mailfile) != NULL) { X if (first_word(buffer,"From ")) { X if (real_from(buffer, from_whom)) { X subj = 0; X in_header = 1; X } X } X else if (in_header) { 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,"From:") || X first_word(buffer, ">From:")) X parse_arpa_from(buffer, from_whom); X else if (buffer[0] == LINEFEED) { X if (verbose && count == 0) X printf("%s contains the following messages:\n\n", X user_mailbox?"Your mailbox" : "Folder"); X in_header = 0; /* in body of message! */ X show_header(count+1, from_whom, subject); X from_whom[0] = 0; X subject[0] = 0; X count++; X } X } X } X return(count); 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]; X X junk[0] = '\0'; X sscanf(buffer, "%*s %s %*s %*s %*s %*s %s", X who, junk); 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], holding_from[SLEN]; X X machine[0] = '\0'; X holding_from[0] = '\0'; X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %s", X holding_from, 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 holding_from, machine); X X if (machine[0] == '\0') /* try for srm address */ X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s", X holding_from, machine); X X if (machine[0] == '\0') X sprintf(buff, holding_from[0] ? holding_from : "anonymous"); X else X sprintf(buff,"%s!%s", machine, holding_from); X X strncpy(who, buff, SLEN); 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(count, from, subject) Xint count; Xchar *from, *subject; 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 X char buffer[SLEN]; X int loc, i=0, exc=0; X X#ifndef INTERNET X char *p; X X if (chloc(from,'!') != -1 && chloc(from,'@') > 0) { X for (p=from;*p != '@'; p++) ; X *p = '\0'; X } 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 while (loc < strlen(from) && loc < SLEN) X buffer[i++] = from[loc++]; X buffer[i] = '\0'; X if (number) X printf("%3d: %-20s %s\n", count, buffer, subject); X else X printf("%-20s %s\n", buffer, subject); X } X else X if (number) X printf("%3d: %-20s %s\n", count, from, subject); X else X printf("%-20s %s\n", 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 two formats: X From: Dave Taylor <hpcnou!dat> X or From: hpcnou!dat (Dave Taylor) 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 X/* this stuff copied from src/addr_util.c */ X#ifdef USE_EMBEDDED_ADDRESSES X X /** if we have a null string at this point, we must just have a X From: line that contains an address only. At this point we X can have one of a few possibilities... X X From: address X From: <address> X From: address () X **/ X X if (strlen(temp) == 0) { X if (lastch(buffer) != '>') { X for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++) X temp[j++] = buffer[i]; X temp[j] = '\0'; X } X else { /* get outta '<>' pair, please! */ X for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--) X temp[j++] = buffer[i]; X temp[j] = '\0'; X reverse(temp); X } X } X#endif 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 /* remove surrounding paired quotation marks */ X if((temp[i] == '"') & (*temp == '"')) { 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 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 2.3 89/03/25 21:47:50 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.3 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: listalias.c,v $ X * Revision 2.3 89/03/25 21:47:50 syd X * Initial 2.2 Release checkin 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, 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 2.3 89/03/25 21:47:51 syd Exp $ X# Copyright (c) 1986, 1987 Dave Taylor X# Copyright (c) 1988, 1989 USENET Community Trust X# Bug reports, patches, comments, suggestions should be sent to: X# X# Syd Weinstein, Elm Coordinator - elm@dsinc.UUCP X# dsinc!elm X# X# $Log: mailrc.awk,v $ X# Revision 2.3 89/03/25 21:47:51 syd X# Initial 2.2 Release checkin 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 2.1 89/03/03 17:46:59 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 2.7 89/03/25 21:47:53 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.7 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X * Copyright (c) 1988, 1989 USENET Community Trust X ******************************************************************************* X * Bug reports, patches, comments, suggestions should be sent to: X * X * Syd Weinstein, Elm Coordinator X * elm@dsinc.UUCP dsinc!elm X * X ******************************************************************************* X * $Log: newalias.c,v $ X * Revision 2.7 89/03/25 21:47:53 syd X * Initial 2.2 Release checkin 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 X#ifdef BSD X# include <sys/file.h> 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 close(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]; 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; 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 no_ret(buffer); 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; X long additive = 1L; X X word = buf; /* use the allocated space! */ 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); SHAR_EOF echo "End of part 23" echo "File utils/newalias.c is continued in part 24" echo "24" > s2_seq_.tmp exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.