home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i071: Smail, UUCP domain maielr, Part03/03
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: Larry Auton <clyde.ATT.COM!lda>
- Posting-number: Volume 11, Issue 71
- Archive-name: smail3/Part03
-
- # This is a shell archive. Remove anything before this line, then
- # unpack it by saving it in a file and typing "sh file". (Files
- # unpacked will be owned by you and have default permissions.)
- #
- # This archive contains:
- # lcasep.c main.c make.cf.sh map.c misc.c mkfnames.sh nptx.c patchlevel
- # pathproc.sh pw.c resolve.c smail.prompt str.c svbinmail.c sysexits.h
- # template.cf
-
- echo x - lcasep.c
- cat > "lcasep.c" << '//E*O*F lcasep.c//'
- /*
- ** convert the host name on a pathalias line to lower case
- */
-
- #ifndef lint
- static char *sccsid="@(#)lcasep.c 2.5 (smail) 9/15/87";
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
-
- # define lower(c) ( isupper(c) ? c-'A'+'a' : c )
-
- void exit(), perror();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *ifp, *ofp;
- char buf[BUFSIZ];
- register char *p;
- int c;
-
- extern int optind;
- extern char *optarg;
-
- ifp = stdin;
- ofp = stdout;
-
- while((c = getopt(argc, argv, "f:o:")) != EOF) {
- switch(c) {
- case 'f':
- if((ifp = fopen(optarg, "r")) == NULL) {
- (void) fprintf(stderr, "%s: can't open %s: ",
- argv[0], optarg);
- perror("");
- exit(1);
- }
- break;
- case 'o':
- if((ofp = fopen(optarg, "w")) == NULL) {
- (void) fprintf(stderr, "%s: can't open %s: ",
- argv[0], optarg);
- perror("");
- exit(1);
- }
- break;
- default:
- (void) fprintf(stderr,
- "usage: %s [-f file] [-o outfile]\n", argv[0]);
- exit(1);
- /* NOTREACHED */
- break;
- }
- }
-
- while(fgets(buf, sizeof(buf), ifp) != NULL) {
- for(p = buf; *p != '\t' && *p != '\0' ; p++) {
- (void) fputc(lower(*p), ofp);
- }
- (void) fputs(p, ofp);
- }
- return(0);
- }
- //E*O*F lcasep.c//
-
- echo x - main.c
- cat > "main.c" << '//E*O*F main.c//'
- /*
- **
- ** rmail/smail - UUCP mailer with automatic routing.
- **
- ** Christopher Seiwald /+\
- ** chris@cbosgd.att.com +\
- ** January, 1985 \+/
- **
- */
-
- #ifndef lint
- static char *sccsid="@(#)main.c 2.5 (smail) 9/15/87";
- #endif
-
- /*
- **
- ** usage: rmail [options] address...
- ** smail [options] address...
- ** options:
- ** -d debug - verbose and don't invoke mailers.
- ** -v verbose - just verbose.
- ** -A print mapped addresses. don't invoke mailers.
- ** -h hostname set hostname
- ** -H hostdomain set hostdomain (default hostname.MYDOM)
- ** -p pathfile path database filename
- ** -r force routing of host!address
- ** -R reroute even explicit path!user
- ** -l user@domain goes to local mailer
- ** -L all mail goes local
- ** -q number mail queueing cost threshold
- ** -m number limit on number of uux_noqueue jobs
- ** -u string string of flags for uux
- ** -F address name to substitute in From: line
- ** -a aliasfile aliases filename (not used with SENDMAIL)
- ** -n namelist list of full names for simple aliases
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "defs.h"
-
- int exitstat = 0; /* exit status, set by resolve, deliver */
-
- enum edebug debug = NO; /* set by -d or -v option */
- enum ehandle handle = HANDLE; /* which mail we can handle, see defs.h */
- enum erouting routing = ROUTING;/* to route or not to route, see defs.h */
-
- char hostname[SMLBUF] = ""; /* set by -h, defaults in defs.h */
- char hostdomain[SMLBUF] = ""; /* set by -H, defaults in defs.h */
- char hostuucp[SMLBUF] = ""; /* built with hostname+".UUCP" */
-
- char *pathfile = PATHS; /* or set by -p */
- char *uuxargs = NULL; /* or set by -u */
-
- char *aliasfile =
- #ifdef ALIAS
- ALIAS; /* or set by -a */
- #else
- NULL;
- #endif
-
- char *fnlist =
- #ifdef FULLNAME
- FULLNAME; /* or set by -n */
- #else
- NULL;
- #endif
-
- int queuecost = QUEUECOST; /* or set by -q */
- char *from_addr = NULL; /* or set by -F */
- int maxnoqueue = MAXNOQUEUE; /* or set by -m */
-
- int getcost =
- #ifdef GETCOST
- 1; /* get cost of path even if not routing */
- #else
- 0;
- #endif
-
- char *spoolfile = NULL; /* name of the file containing letter */
- FILE *spoolfp; /* file pointer to spoolfile */
- int spoolmaster = 0; /* indicates 'control' of spoolfile */
-
- void spool();
-
-
- /*
- **
- ** rmail/smail: mail stdin letter to argv addresses.
- **
- ** After processing command line options and finding our host and domain
- ** names, we map addresses into <host,user,form,cost> sets. Then we deliver.
- **
- */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *hostv[MAXARGS]; /* UUCP neighbor */
- char *userv[MAXARGS]; /* address given to host */
- int costv[MAXARGS]; /* cost of resolved route */
- enum eform formv[MAXARGS]; /* invalid, local, or uucp */
- char *p;
- int c;
- int printaddr = 0; /* or set by -A */
- int nargc;
- char **nargv, **alias();
-
- char *optstr = "cdvArRlLH:h:p:u:q:a:n:m:f:F:";
- extern char *optarg;
- extern int optind;
-
- /*
- ** see if we aren't invoked as rmail
- */
- if((p = rindex(argv[0], '/')) == NULL) {
- p = argv[0];
- } else {
- p++;
- }
-
- if(*p != 'r' ) {
- handle = ALL;
- }
-
- /*
- ** Process command line arguments
- */
- while ((c = getopt(argc, argv, optstr)) != EOF) {
- switch ( c ) {
- case 'd': debug = YES; break;
- case 'v': debug = VERBOSE; break;
- case 'A': printaddr = 1; break;
- case 'F': from_addr = optarg; break;
- case 'r': routing = ALWAYS; break;
- case 'R': routing = REROUTE; break;
- case 'l': handle = JUSTUUCP; break;
- case 'L': handle = NONE; break;
- case 'f': spoolfile = optarg; break;
- case 'p': pathfile = optarg; break;
- case 'u': uuxargs = optarg; break;
- case 'a': aliasfile = optarg; break;
- case 'n': fnlist = optarg; break;
- case 'H': (void) strcpy(hostdomain, optarg); break;
- case 'h': (void) strcpy(hostname, optarg); break;
- case 'm': if(isdigit(*optarg)) {
- maxnoqueue = atoi(optarg);
- }
- break;
- case 'c': getcost = 1; break;
- case 'q': if(isdigit(*optarg)) {
- queuecost = atoi(optarg);
- }
- break;
- default:
- error( EX_USAGE, "valid flags are %s\n", optstr);
- }
- }
- if ( argc <= optind ) {
- error( EX_USAGE, "usage: %s [flags] address...\n", argv[0] );
- }
-
- /*
- ** Get our default hostname and hostdomain.
- */
- getmynames();
-
- /*
- ** Spool the letter in a temporary file.
- */
- nargc = argc - optind;
- if(printaddr == 0) {
- spool(nargc, &argv[optind]);
- }
-
- /*
- ** Do aliasing and fullname resolution
- */
- nargv = alias(&nargc, &argv[optind]);
-
- /*
- ** Map argv addresses to <host, user, form, cost>.
- */
- map(nargc, nargv, hostv, userv, formv, costv);
- /*
- ** If all we want it mapped addresses, print them and exit.
- */
- if(printaddr) {
- int i;
- char abuf[SMLBUF];
- for(i=nargc-1; i >= 0; i--) {
- if(formv[i] == ERROR) {
- (void) strcpy(abuf, nargv[i]);
- } else {
- build(hostv[i], userv[i], formv[i], abuf);
- }
- (void) fputs(abuf, stdout);
- if(i != 0) (void) putchar(' ');
- }
- (void) putchar('\n');
- exit(0);
- }
- /*
- ** Deliver.
- */
- deliver(nargc, hostv, userv, formv, costv);
- /*
- ** Exitstat was set if any resolve or deliver failed, otherwise 0.
- */
- return( exitstat );
- }
- //E*O*F main.c//
-
- echo x - make.cf.sh
- cat > "make.cf.sh" << '//E*O*F make.cf.sh//'
- #! /bin/sh
- #
- # @(#)make.cf.sh 2.5 (smail) 9/15/87
- #
- cat <<!EOM!
- This script will prompt you for the automatically configurable parameters
- in the stock version of the sendmail configuration file. Naturally, any
- local extensions will have to be added manually.
-
- Clyde is a VAX running AT&T System V Release 2.0, with a port of sendmail.
- Clyde is a gateway for the domain .att.com.
-
- Below is a trace of the session that
- configured the sendmail.cf on clyde.ATT.COM:
- ===
-
- !EOM!
-
- echo "press return to continue"; read foo
-
- cat <<!EOM!
- Enter Date (MM-DD-YY):
- 06-24-86
- Enter This Host's Name:
- clyde
- Enter This Host's Official Domain:
- ATT.COM
- Enter Any Equivalent Domain Classes:
- ATT
- Enter Any Domains For Which This Host Is An Authority:
- ATT.UUCP
- Does This Host Have SMTP Connections (y/n)?
- no
- Enter Full Path to Executable That Will Provide Local Mail Delivery:
- /bin/lmail
- Is /bin/lmail A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?
- no
- Will This Host Act As A Gateway Between Domains (y/n)?
- yes
- Are subdomains beneath this hosts' domain to be hidden (y/n)?
- yes
- ===
- !EOM!
- # get date of configuration
- CF_DATE=`/bin/sh ./smail.prompt string "Enter Date (MM-DD-YY):"`
-
- # get host name
- CF_HOST=`/bin/sh ./smail.prompt string "Enter This Host's Name:"`
-
- # get host domain
- CF_DOMAIN=`/bin/sh ./smail.prompt string "Enter This Host's Official Domain:"`
-
- # get domain classes
- CF_DCLASS=`/bin/sh ./smail.prompt string "Enter Any Equivalent Domain Classes:"`
-
- # get domain authority
- CF_AUTHORITY=`/bin/sh ./smail.prompt string "Enter Any Domains For Which This Host Is An Authority:"`
-
- CF_SMTP=`/bin/sh ./smail.prompt yesno "Does This Host Have SMTP Connections (y/n)?"`
- if test "$CF_SMTP" = "yes"
- then
-
- #get list of local SMTP connections
- CF_SMTP=`/bin/sh ./smail.prompt file "Enter Full Path to File that Contains List of SMTP Connections:"`
-
- CF_SMTP="FE$CF_SMTP %s"
- else
- CF_SMTP=""
- fi
-
- # get path to local delivery agent
- CF_LOCALMAIL=`/bin/sh ./smail.prompt file "Enter Full Path to Executable That Will Provide Local Mail Delivery:"`
-
- CF_SYSTEM=`/bin/sh ./smail.prompt yesno "Is $CF_LOCALMAIL A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?"`
- if test "$CF_SYSTEM" = "yes"
- then
- CF_SVMAIL="#"
- CF_BSMAIL=""
- else
- CF_SVMAIL=""
- CF_BSMAIL="#"
- fi
-
- CF_GATEWAY=`/bin/sh ./smail.prompt yesno "Will This Host Act As A Gateway Between Domains(y/n)?"`
- if test "$CF_GATEWAY" = "yes"
- then
- CF_GATEWAY=""
- else
- CF_GATEWAY="#"
- fi
-
- CF_HIDDENHOSTS=`/bin/sh ./smail.prompt yesno "Are subdomains beneath this hosts' domain to be hidden (y/n)?"`
- if test "$CF_HIDDENHOSTS" = "yes"
- then
- CF_HIDDENHOSTS=""
- else
- CF_HIDDENHOSTS="#"
- fi
-
- sed \
- -e "s/CF_HOST/Dw$CF_HOST/" \
- -e "s/CF_DOMAIN/DD$CF_DOMAIN/" \
- -e "s/CF_AUTHORITY/DA$CF_AUTHORITY/" \
- -e "s/CF_DCLASS/CDUUCP $CF_DCLASS/" \
- -e "s;CF_SMTP;$CF_SMTP;" \
- -e "s;CF_DATE;$CF_DATE;" \
- -e "s;CF_LOCALMAIL;$CF_LOCALMAIL;" \
- -e "s;CF_BSMAIL;$CF_BSMAIL;" \
- -e "s;CF_SVMAIL;$CF_SVMAIL;" \
- -e "s;CF_GATEWAY;$CF_GATEWAY;" \
- -e "s;CF_HIDDENHOSTS;$CF_HIDDENHOSTS;" \
- template.cf > sendmail.cf
- //E*O*F make.cf.sh//
-
- echo x - map.c
- cat > "map.c" << '//E*O*F map.c//'
- #ifndef lint
- static char *sccsid="@(#)map.c 2.5 (smail) 9/15/87";
- #endif
-
- # include <stdio.h>
- # include <sys/types.h>
- # include "defs.h"
-
- extern int queuecost;
-
- /*
- **
- ** map(): map addresses into <host, user, form, cost> sets.
- **
- ** Calls resolve() for each address of argv. The result is hostv and
- ** userv arrays (pointing into buffers userz and hostz), and formv array.
- **
- */
-
- map(argc, argv, hostv, userv, formv, costv)
- int argc; /* address count */
- char **argv; /* address vector */
- char *hostv[]; /* remote host vector */
- char *userv[]; /* user name vector */
- enum eform formv[]; /* address format vector */
- int costv[]; /* cost vector */
- {
- int i, cost;
- enum eform resolve();
- char *c;
- static char userbuf[BIGBUF], *userz;
- static char hostbuf[BIGBUF], *hostz;
-
- userz = userbuf;
- hostz = hostbuf;
-
- for( i=0; i<argc; i++ ) {
- #ifdef DEFQUEUE
- cost = queuecost+1; /* default is queueing */
- #else
- cost = queuecost-1; /* default is no queueing */
- #endif
- userv[i] = userz; /* put results here */
- hostv[i] = hostz;
- if ( **argv == '(' ) { /* strip () */
- ++*argv;
- c = index( *argv, ')' );
- if (c)
- *c = '\0';
- }
- /* here it comes! */
- formv[i] = resolve(*argv++, hostz, userz, &cost);
- costv[i] = cost;
- userz += strlen( userz ) + 1; /* skip past \0 */
- hostz += strlen( hostz ) + 1;
- }
- }
- //E*O*F map.c//
-
- echo x - misc.c
- cat > "misc.c" << '//E*O*F misc.c//'
-
- /*
- ** Miscellaneous support functions for smail/rmail
- */
-
- #ifndef lint
- static char *sccsid="@(#)misc.c 2.5 (smail) 9/15/87";
- #endif
-
- # include <stdio.h>
- # include <sys/types.h>
- # include <ctype.h>
- # include "defs.h"
- #ifdef BSD
- # include <sys/time.h>
- # include <sys/timeb.h>
- #else
- # include <time.h>
- # include <sys/utsname.h>
- #endif
-
- extern int exitstat; /* set if a forked mailer fails */
- extern enum edebug debug; /* how verbose we are */
- extern enum ehandle handle; /* what we handle */
- extern char *uuxargs; /* arguments given to uux */
- extern int queuecost; /* threshold for queueing mail */
- extern int maxnoqueue; /* max number of uucico's */
- extern enum erouting routing; /* when to route addresses */
- extern char hostdomain[]; /* */
- extern char hostname[]; /* */
- extern char hostuucp[]; /* */
- extern char *pathfile; /* location of path database */
- extern char *spoolfile; /* file name of spooled message */
- extern FILE *spoolfp; /* file ptr to spooled message */
- extern int spoolmaster; /* set if creator of spoolfile */
-
- extern struct tm *localtime();
-
- struct tm *gmt, *loc; /* GMT and local time structure */
- time_t now; /* current system time */
- char nows[50]; /* time in ctime format */
- char arpanows[50]; /* time in arpa format */
-
- # ifdef LOG
- void
- log(command, from, size)
- char *command, *from;
- long size;
- {
- FILE *fd;
- char *logtime, tbuf[50];
- int cmask;
-
- logtime = strcpy(tbuf, nows);
- logtime[16] = '\0';
- logtime += 4;
-
- cmask = umask(0);
- fd = fopen(LOG, "a");
- (void) umask(cmask);
-
- if (fd != NULL) {
- (void) fprintf(fd, "%s\t%ld\t%s\t%s\n",
- logtime, size, from, command);
- (void) fclose(fd);
- }
- }
- # endif
-
- # ifdef RECORD
- FILE *
- record(command, from, size)
- char *command, *from;
- long size;
- {
- FILE *fd;
- char *logtime, buf[SMLBUF];
- int cmask;
-
- logtime = strcpy(buf, nows);
- logtime[16] = 0;
- logtime += 4;
-
- cmask = umask(0);
- fd = fopen(RECORD, "a");
- (void) umask(cmask);
-
- if (fd != NULL) {
- (void) fprintf(fd, "%s: %s, from %s, %ld bytes\n",
- logtime, command, from, size);
- }
- while(fgets(buf, sizeof(buf), spoolfp) != NULL) {
- (void) fputs(buf, fd);
- }
- (void) fclose(fd);
- }
- # endif
-
-
- setdates()
- {
- time_t time();
- struct tm *gmtime();
- char *ctime(), *arpadate();
-
- (void) time(&now);
- (void) strcpy(nows, ctime(&now));
- gmt = gmtime(&now);
- loc = localtime(&now);
- (void) strcpy(arpanows, arpadate(nows));
- }
-
- /*
- ** Note: This routine was taken from sendmail
- **
- ** ARPADATE -- Create date in ARPANET format
- **
- ** Parameters:
- ** ud -- unix style date string. if NULL, one is created.
- **
- ** Returns:
- ** pointer to an ARPANET date field
- **
- ** Side Effects:
- ** none
- **
- ** WARNING:
- ** date is stored in a local buffer -- subsequent
- ** calls will overwrite.
- **
- ** Bugs:
- ** Timezone is computed from local time, rather than
- ** from whereever (and whenever) the message was sent.
- ** To do better is very hard.
- **
- ** Some sites are now inserting the timezone into the
- ** local date. This routine should figure out what
- ** the format is and work appropriately.
- */
-
- char *
- arpadate(ud)
- register char *ud;
- {
- register char *p;
- register char *q;
- static char b[40];
- extern char *ctime();
- register int i;
- #ifndef BSD
- extern char *tzname[];
- time_t t, time();
- #else
- /* V7 and 4BSD */
- struct timeb t;
- extern struct timeb *ftime();
- extern char *timezone();
- #endif
-
- /*
- ** Get current time.
- ** This will be used if a null argument is passed and
- ** to resolve the timezone.
- */
-
- #ifndef BSD
- (void) time(&t);
- if (ud == NULL)
- ud = ctime(&t);
- #else
- /* V7 or 4BSD */
- ftime(&t);
- if (ud == NULL)
- ud = ctime(&t.time);
- #endif
-
- /*
- ** Crack the UNIX date line in a singularly unoriginal way.
- */
-
- q = b;
-
- p = &ud[8]; /* 16 */
- if (*p == ' ')
- p++;
- else
- *q++ = *p++;
- *q++ = *p++;
- *q++ = ' ';
-
- p = &ud[4]; /* Sep */
- *q++ = *p++;
- *q++ = *p++;
- *q++ = *p++;
- *q++ = ' ';
-
- p = &ud[22]; /* 1979 */
- *q++ = *p++;
- *q++ = *p++;
- *q++ = ' ';
-
- p = &ud[11]; /* 01:03:52 */
- for (i = 8; i > 0; i--)
- *q++ = *p++;
-
- /* -PST or -PDT */
- #ifndef BSD
- p = tzname[localtime(&t)->tm_isdst];
- #else
- p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
- #endif
- if (p[3] != '\0')
- {
- /* hours from GMT */
- p += 3;
- *q++ = *p++;
- if (p[1] == ':')
- *q++ = '0';
- else
- *q++ = *p++;
- *q++ = *p++;
- p++; /* skip ``:'' */
- *q++ = *p++;
- *q++ = *p++;
- }
- else
- {
- *q++ = ' ';
- *q++ = *p++;
- *q++ = *p++;
- *q++ = *p++;
- }
-
- p = &ud[0]; /* Mon */
- *q++ = ' ';
- *q++ = '(';
- *q++ = *p++;
- *q++ = *p++;
- *q++ = *p++;
- *q++ = ')';
-
- *q = '\0';
- return (b);
- }
-
- /*
- * The user name "postmaster" must be accepted regardless of what
- * combination of upper and lower case is used. This function is
- * used to convert all case variants of "postmaster" to all lower
- * case. If the user name passed in is not "postmaster", it is
- * returned unchanged.
- */
- char *
- postmaster(user)
- char *user;
- {
- static char *pm = "postmaster";
-
- if(strcmpic(user, pm) == 0) {
- return(pm);
- } else {
- return(user);
- }
- }
-
- /*
- * Return 1 iff the string is "UUCP" (ignore case).
- */
- isuucp(str)
- char *str;
- {
- if(strcmpic(str, "UUCP") == 0) {
- return(1);
- } else {
- return(0);
- }
- }
-
- /*
- ** sform(form) returns a pointer to a string that tells what 'form' means
- */
-
- char *
- sform(form)
- enum eform form;
- {
- if(form == ERROR) return("ERROR");
- if(form == LOCAL) return("LOCAL");
- if(form == DOMAIN) return("DOMAIN");
- if(form == UUCP) return("UUCP");
- if(form == ROUTE) return("ROUTE");
- return("UNKNOWN");
- }
-
- /*
- **
- ** getmynames(): what is my host name and host domain?
- **
- ** Hostname set by -h, failing that by #define HOSTNAME, failing
- ** that by gethostname() or uname().
- **
- ** Hostdomain set by -h, failing that by #define HOSTDOMAIN,
- ** failing that as hostname.MYDOM, or as just hostname.
- **
- ** See defs.h for the inside story.
- **
- */
-
- getmynames()
- {
- #ifdef HOSTNAME
- if (!*hostname)
- (void) strcpy(hostname, HOSTNAME);
- #endif
- #ifdef GETHOSTNAME
- if (!*hostname)
- gethostname(hostname, SMLBUF - 1);
- #endif
- #ifdef UNAME
- if (!*hostname) {
- struct utsname site;
-
- if (uname(&site) < 0)
- error(EX_SOFTWARE, "uname() call failed", 0);
- (void) strcpy(hostname, site.nodename);
- }
- #endif
- if (!*hostname)
- error(EX_SOFTWARE, "can't determine hostname.\n", 0);
- #ifdef HOSTDOMAIN
- if (!*hostdomain)
- (void) strcpy(hostdomain, HOSTDOMAIN);
- #endif
- #ifdef MYDOM
- if (!*hostdomain)
- (void) strcat(strcpy(hostdomain, hostname), MYDOM);
- #endif
- if (!*hostdomain)
- (void) strcpy(hostdomain, hostname);
-
- (void) strcat(strcpy(hostuucp, hostname), ".UUCP");
- }
- //E*O*F misc.c//
-
- echo x - mkfnames.sh
- cat > "mkfnames.sh" << '//E*O*F mkfnames.sh//'
- #! /bin/sh
- #
- # @(#)mkfnames.sh 2.5 (smail) 9/15/87
- #
- if test $# = 0
- then
- sed 's/\(.*\):.*:.*:.*:\(.*\):.*:.*/\1 \2/' /etc/passwd
- else
- cat $*
- fi | # at this point, we have a list of login\tFull Name pairs
- nptx |
- lcasep |
- sort -u +0 -1
- //E*O*F mkfnames.sh//
-
- echo x - nptx.c
- cat > "nptx.c" << '//E*O*F nptx.c//'
- #ifndef lint
- static char *sccsid = "@(#)nptx.c 2.5 (smail) 9/15/87";
- #endif
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <pwd.h>
- #include "defs.h"
- #include <ctype.h>
-
- char *malloc(), *index(), *fullname();
- void nptx(), free(), dotspace();
-
- enum edebug debug; /* not used by nptx */
- char *fnlist = NULL; /* not used by nptx */
-
- main()
- {
- int i;
- char buf[SMLBUF], *p, *name, *last, *nick, *ctmp;
-
- while(gets(buf) != NULL) {
- /* line should be in form
- **
- ** login First Last
- ** or
- ** login First Last(Nickname)
- **
- */
- if((p = index(buf, '\t')) == NULL) {
- (void) fprintf(stderr, "format error: %s\n", buf);
- continue;
- }
-
- *p++ = '\0';
- name = fullname(p);
- dotspace(name);
-
- if (last = rindex(name, '.')) {
- last++;
- } else {
- last = NULL;
- }
-
- if ((nick = index(p, '(')) != NULL) {
- nick++;
- if ((ctmp = index(nick, ')')) == NULL) {
- nick = NULL;
- } else {
- *ctmp = '\0';
- }
- }
-
- nptx(buf, name);
-
- if((last != NULL) && (nick != NULL)) {
- i=strlen(nick) + strlen(last) + 2;
- if((name = malloc(i)) != NULL) {
- (void) strcpy(name, nick);
- (void) strcat(name, ".");
- (void) strcat(name, last);
- dotspace(name);
- nptx(buf, name);
- free(name);
- }
- }
- }
- return(0);
- }
-
- void
- dotspace(s)
- char *s;
- {
- register char *p, *t;
-
- /* turn whitespace to '.' */
- for(p = s; *p != '\0'; p++) {
- if((*p == ' ') || (*p == '\t')) {
- *p = '.';
- }
- }
-
- /* elide leading '.'s */
- for(p = s; *p == '.' ; p++)
- ;
-
- /* elide mulitple '.'s and all "'"s */
- for(t = s; *p != '\0'; p++, t++) {
- *t = *p;
-
- if(*t == '\'') {
- t--;
- continue;
- }
-
- if(*p == '.') {
- while(*(++p) == '.')
- ;
- p--;
- }
- }
- *t = '\0';
-
- /* elide trailing '.' */
- if((t > s) && (*(--t) == '.')) *t = '\0';
- }
-
- void
- nptx(login, name)
- char *login, *name;
- {
- int i,j,k,N,lim,mask;
- int ii,ji,ki,Ni,limi,maski;
- char nl[11][100], il[11][100];
- char *pi, *p, *rindex();
- char buf[100];
- char bufi[100];
-
- if((name == NULL) || (*name == '\0')) {
- return;
- }
-
- for(i=0; i < 10; i++) {
- if((p = rindex(name, '.')) == NULL) break;
- (void) strcpy(nl[i], p+1);
- *p = NULL;
- }
- (void) strcpy(nl[i], name);
-
- while((strcmpic(nl[i], "Mr" ) == 0)
- || (strcmpic(nl[i], "Dr" ) == 0)
- || (strcmpic(nl[i], "Mrs" ) == 0)
- || (strcmpic(nl[i], "Miss") == 0)
- || (strcmpic(nl[i], "Ms" ) == 0)) {
- i--;
- }
-
- while((strcmpic(nl[0], "Jr") == 0)
- || (strcmpic(nl[0], "Sr") == 0)) {
- for(j=0; j < i; j++) {
- (void) strcpy(nl[j], nl[j+1]);
- }
- i--;
- }
-
- N = i;
- lim = 1 << (N+1);
- for(mask = 1 << N ; mask < lim ; mask++) {
- buf[0] = '\0';
- for(j = 1, k = N; j < lim; j <<=1, k--) {
- if(j & mask) {
- (void) strcat(buf, nl[k]);
- (void) strcat(buf, ".");
- }
- }
- if((p = rindex(buf, '.')) != NULL) {
- *p = '\0';
- }
-
- for(ii=0; ii < 10; ii++) {
- if((pi = rindex(buf, '.')) == NULL) break;
- (void) strcpy(il[ii], pi+1);
- *pi = NULL;
- }
- (void) strcpy(il[ii], buf);
- Ni = ii;
- limi = 1 << (Ni+1);
- for(maski = 1 << Ni /* 0 */ ; maski < limi ; maski++) {
- bufi[0] = '\0';
- for(ji = 1, ki = Ni; ji < limi; ji <<=1, ki--) {
- if(ji & maski) {
- (void) strcat(bufi, il[ki]);
- } else {
- char init[3];
- init[0] = il[ki][0];
- init[1] = '\0';
- (void) strcat(bufi, init);
- }
- (void) strcat(bufi, ".");
- }
- if((pi = rindex(bufi, '.')) != NULL) {
- *pi = '\0';
- }
- #ifdef DOT_REQD
- if(index(bufi, '.') == NULL) {
- continue;
- }
- #endif /* DOT_REQD */
- (void) printf("%s\t%s\n",bufi, login); /* */
- }
- }
- }
- //E*O*F nptx.c//
-
- echo x - patchlevel
- cat > "patchlevel" << '//E*O*F patchlevel//'
- Patch #: 00
- //E*O*F patchlevel//
-
- echo x - pathproc.sh
- cat > "pathproc.sh" << '//E*O*F pathproc.sh//'
- #
- # @(#)pathproc.sh 2.5 (smail) 9/15/87
- #
- # This script will do all that's necessary for
- # transforming the output of pathalias -f into
- # the format of a 'paths' file for smail.
- #
- # format of the pathalias -f output is
- # cost host route
- #
- # format of a 'paths' file for smail is
- # host route first_hop_cost
- #
- # move cost field to end of line
- #
- sed 's/\(.*\) \(.*\) \(.*\)/\2 \3 \1/'|
- #
- # convert target domain/host to lower case
- #
- lcasep |
- #
- # sort the stream
- #
- sort
- //E*O*F pathproc.sh//
-
- echo x - pw.c
- cat > "pw.c" << '//E*O*F pw.c//'
- #ifndef lint
- static char *sccsid = "@(#)pw.c 2.5 (smail) 9/15/87";
- #endif
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <pwd.h>
- #include "defs.h"
- #include <ctype.h>
-
- char *malloc();
- void free();
-
- typedef struct pw_node pwlist;
-
- struct pw_node {
- char *lname; /* login name */
- char *fname; /* full name */
- int uid; /* user-id */
- char *home; /* login name */
- pwlist *vlink; /* link to next item */
- };
-
- pwlist *pwhead; /* head of linked list */
- pwlist *pwparse(); /* head of linked list */
-
- #define PNULL ((pwlist *) 0)
-
- char *
- pwfnam(user)
- char *user;
- {
- pwlist *f;
-
- /*
- ** check for previously cached user
- */
-
- for(f=pwhead; f != NULL; f=f->vlink) {
- if(strcmp(user, f->lname) == 0) {
- return(f->fname);
- }
- }
- /*
- ** not found parse the password file
- */
-
- while((f=pwparse()) != PNULL) {
- if(strcmp(user, f->lname) == 0) {
- return(f->fname);
- }
- }
- return(NULL);
- }
-
- char *
- pwuid(uid)
- int uid;
- {
- pwlist *f;
-
- /*
- ** check for previously cached user
- */
-
- for(f=pwhead; f != NULL; f=f->vlink) {
- if(uid == f->uid) {
- return(f->lname);
- }
- }
- /*
- ** not found parse the password file
- */
-
- while((f=pwparse()) != PNULL) {
- if(uid == f->uid) {
- return(f->lname);
- }
- }
- return(NULL);
- }
-
- #ifndef SENDMAIL
- char *
- tilde(user)
- char *user;
- {
- pwlist *f;
-
- /*
- ** check for previously cached user
- */
-
- for(f=pwhead; f != NULL; f=f->vlink) {
- if(strcmp(user, f->lname) == 0) {
- return(f->home);
- }
- }
- /*
- ** not found parse the password file
- */
-
- while((f=pwparse()) != PNULL) {
- if(strcmp(user, f->lname) == 0) {
- return(f->home);
- }
- }
- return(NULL);
- }
- #endif /* not SENDMAIL */
-
- char *
- fullname(gecos)
- char *gecos;
- {
- static char fname[SMLBUF];
- register char *cend;
-
- (void) strcpy(fname, gecos);
- if (cend = index(fname, ','))
- *cend = '\0';
- if (cend = index(fname, '('))
- *cend = '\0';
- /*
- ** Skip USG-style 0000-Name nonsense if necessary.
- */
- if (isdigit(*(cend = fname))) {
- if ((cend = index(fname, '-')) != NULL)
- cend++;
- else
- /*
- ** There was no `-' following digits.
- */
- cend = fname;
- }
- return (cend);
- }
-
- pwlist *
- pwparse()
- {
- pwlist *f;
- char *p, *name;
- struct passwd *pwent, *getpwent();
- unsigned int i;
- static int pw_eof = 0;
-
- if((pw_eof == 1)
- || ((pwent = getpwent()) == (struct passwd *) NULL)) {
- pw_eof = 1;
- return(PNULL);
- }
- /*
- ** Get an entry from the password file.
- ** Parse relevant strings.
- */
- f = (pwlist *) malloc(sizeof(pwlist));
- if(f == PNULL) return(PNULL);
-
- f->vlink = pwhead;
- pwhead = f;
- f->uid = pwent->pw_uid;
-
- i=strlen(pwent->pw_name)+1;
- p = malloc(i);
- if(p == NULL) return(PNULL);
- f->lname = strcpy(p, pwent->pw_name);
-
- i=strlen(pwent->pw_dir)+1;
- p = malloc(i);
- if(p == NULL) return(PNULL);
- f->home = strcpy(p, pwent->pw_dir);
-
- name = fullname(pwent->pw_gecos);
- i=strlen(name)+1;
- p = malloc(i);
- if(p == NULL) return(PNULL);
- f->fname = strcpy(p, name);
- return(f);
- }
-
- #ifdef FULLNAME
- /*
- ** Resolve a full name to a login name.
- ** Not too much smarts here.
- */
-
- char *
- res_fname(user)
- register char *user;
- {
- long pos, middle, hi, lo;
- static long pathlength = 0;
- register char *s;
- int c;
- static FILE *file;
- int flag;
- char namebuf[SMLBUF], *path;
- extern enum edebug debug;
- extern char *fnlist;
-
-
-
- DEBUG("res_fname: looking for '%s'\n", user);
-
- if(pathlength == 0) { /* open file on first use */
- if((file=fopen(fnlist, "r")) == NULL) {
- DEBUG( "can't access %s.\n", fnlist);
- pathlength = -1;
- } else {
- (void) fseek(file, 0L, 2); /* find length */
- pathlength = ftell(file);
- }
- }
-
- if(pathlength == -1 ) return(NULL);
-
- lo = 0;
- hi = pathlength;
- path = namebuf;
-
- (void) strcpy( path, user );
- (void) strcat( path, "\t" );
-
- for( ;; ) {
- pos = middle = ( hi+lo+1 )/2;
- (void) fseek( file, pos, 0 ); /* find midpoint */
- if (pos != 0) /* to beginning of next line */
- while( ( c=getc( file ) ) != EOF && c != '\n' );
- for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */
- if ( *s == '\0' ) {
- goto solved;
- }
- c = getc( file );
- flag = lower( c ) - lower( *s );
- }
- if (lo >= middle) /* failure? */
- return(NULL);
-
- if(c != EOF && flag < 0) /* close window */
- lo = middle;
- else
- hi = middle - 1;
- }
- /*
- ** Now just copy the result.
- */
- solved:
- while(((c = getc(file)) != EOF) && (c != '\t') && (c != '\n')) {
- *path++ = c;
- }
-
- if(path == namebuf) { /* NULL alias field */
- return(NULL);
- }
-
- *path = '\0';
- if((path = malloc((unsigned) strlen(namebuf)+1)) == NULL) {
- return(NULL); /* sorry, no memory */
- }
-
- (void) strcpy(path, namebuf);
- return(path);
-
- }
- #endif /* FULLNAME */
- //E*O*F pw.c//
-
- echo x - resolve.c
- cat > "resolve.c" << '//E*O*F resolve.c//'
- /*
- **
- ** Resolve.c
- **
- ** Routes then resolves addresses into UUCP or LOCAL.
- **
- */
- #ifndef lint
- static char *sccsid="@(#)resolve.c 2.5 (smail) 9/15/87";
- #endif
-
- #include <ctype.h>
- #include <stdio.h>
- #include "defs.h"
-
- extern int exitstat; /* set if address doesn't resolve */
- extern enum ehandle handle; /* what mail we can handle */
- extern enum edebug debug; /* verbose and debug modes */
- extern enum erouting routing; /* when to route addresses */
- extern char hostdomain[]; /* */
- extern char hostname[]; /* */
- extern char *pathfile; /* location of path database */
- extern int getcost; /* get path cost even if not routing */
-
- char *sform();
-
- /*
- **
- ** rsvp(): how to resolve addresses.
- **
- ** After parsing an address into <form>, the resolved form will be
- ** rsvp( form ). If == ROUTE, we route the parsed address and parse again.
- **
- */
-
- # define rsvp(a) table[(int)a][(int)handle]
-
- enum eform table[5][3] = {
- /* all justuucp none */
- { ERROR, ERROR, ERROR }, /* error */
- { LOCAL, LOCAL, LOCAL }, /* local */
- { ROUTE, LOCAL, LOCAL }, /* domain */
- { UUCP, UUCP, LOCAL }, /* uucp */
- { ERROR, ERROR, ERROR }}; /* route */
-
- /*
- **
- ** resolve(): resolve addresses to <host, user, form>.
- **
- ** This is a gnarly piece of code, but it does it all. Each section
- ** is documented.
- **
- */
-
- enum eform
- resolve( address, domain, user , cost)
- char *address; /* the input address */
- char *domain; /* the returned domain */
- char *user; /* the returned user */
- int *cost; /* the returned cost */
- {
- enum eform form; /* the returned form */
- enum eform parse(); /* to crack addresses */
- int parts; /* to ssplit addresses */
- char *partv[MAXPATH]; /* " " " */
- char temp[SMLBUF]; /* " " " */
- int i;
-
-
- /*
- ** If we set REROUTE and are prepared to deliver UUCP mail, we split the
- ** address apart at !'s and try to resolve successively larger righthand
- ** substrings until we succeed. Otherwise, we just resolve the whole thing
- ** once.
- */
- if ((routing == REROUTE) && (rsvp( UUCP ) == UUCP)) {
- parts = ssplit( address, '!', partv );
- } else {
- parts = 1;
- partv[0] = address;
- }
- /*
- ** This for(i) loop selects successively larger
- ** righthand substrings of the address.
- */
- for( i = parts - 1; i >= 0; i-- ) {
- /*
- ** Parse the address.
- */
- (void) strcpy( temp, partv[i] );
- form = parse( temp, domain, user );
-
- DEBUG("resolve: parse address '%s' = '%s' @ '%s' (%s)\n",
- temp,user,domain,sform(form));
-
- /*
- ** If we are looking at a substring (that's not the entire string)
- ** which parses to a LOCAL address, we skip to the next larger substring.
- */
- if((i != 0) && (form == LOCAL))
- continue;
- /*
- ** Routing, when required, is the next step.
- ** We route the address if we have a ROUTE form
- ** or if we have a UUCP form and we are told to
- ** route ALWAYS or REROUTE (i.e., routing != JUSTDOMAIN)
- */
- if((rsvp( form ) == ROUTE)
- ||((rsvp( form ) == UUCP) && (routing != JUSTDOMAIN ))) {
-
- int look_smart = 0;
-
- if((routing == REROUTE) && (i == 0)) {
- look_smart = 1; /* last chance */
- }
-
- /* route() puts the new route in 'temp' */
- if(route(domain,user,look_smart,temp,cost) != EX_OK) {
- continue; /* If routing fails, try
- /* next larger substring.
- /* */
- }
- /*
- ** After routing, reparse the new route into domain and user.
- */
- form = parse( temp, domain, user );
-
- DEBUG("resolve: parse route '%s' = '%s' @ '%s' (%s)\n",
- temp,user,domain,sform(form));
-
- } else if((getcost) && (rsvp(form) == UUCP)) {
- /* get the cost of the route
- ** even if we're not going route the mail.
- ** this allows smart decisions about using
- ** the -r flag to uux when we're not routing.
- */
- char junk[SMLBUF];
- if(route(domain,user,0,junk,cost) != EX_OK) {
- continue; /* If routing fails, try
- /* next larger substring.
- /* */
- }
- }
- break; /* route is resolved */
- }
- /*
- ** For LOCAL mail in non-local format, we rewrite the full address into
- ** <user> and leave <domain> blank.
- */
- if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
- build( domain, user, form, temp );
- (void) strcpy( user, temp );
- (void) strcpy( domain, "" );
- form = LOCAL;
- }
- /*
- ** If we were supposed to route an address but failed (form == ERROR),
- ** or after routing we are left with an address that still needs to
- ** be routed (rsvp( form ) == ROUTE), complain.
- */
- if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
- exitstat = EX_NOHOST;
- ADVISE("resolve failed '%s' = '%s' @ '%s' (%s)\n",
- address, user, domain, sform(form));
- form = ERROR;
- } else {
- ADVISE("resolve '%s' = '%s' @ '%s' (%s)\n",
- address, user, domain, sform(form));
- }
- return ( form );
- }
-
- /*
- **
- ** route(): route domain, plug in user.
- **
- ** Less complicated than it looks. Each section is documented.
- **
- */
-
- route(domain, user, look_smart, result, cost)
- char *domain; /* domain or host name */
- char *user; /* user name */
- int look_smart; /* do we try to route through a smarter host? */
- char *result; /* output route */
- int *cost; /* cost of output route */
- {
- int uucpdom = 0;
- int domains, step; /* to split domain */
- char *domainv[MAXDOMS]; /* " " " */
- char temp[SMLBUF], path[SMLBUF];
-
- /*
- ** Fully qualify the domain, and then strip the last (top level domain)
- ** component off, so that we look it up separately.
- */
- temp[0] = '.';
- (void) strcpy(temp+1, domain );
-
- domains = ssplit( temp+1, '.', domainv );
-
- /*
- ** check target domain for the local host name and host domain.
- ** if it matches, then skip the lookup in the database.
- ** this prevents mail loops for cases where SMARTHOST is defined
- ** in the routing table, but the local host is not. It also is
- ** a little faster when the local host is the target domain.
- */
- if((strcmpic(domain, hostname) == 0)
- || (strcmpic(domain, hostdomain) == 0)) {
- step = 0;
- *cost = 0;
- (void) strcpy(path, "%s");
- DEBUG("route: '%s' is local\n", domain);
- goto route_complete;
- }
-
- /* If the domain ends in .UUCP, trim that off. */
- if((domains > 0) && isuucp(domainv[domains-1])) {
- domains--;
- domainv[domains][-1] = '\0';
- uucpdom = 1;
- }
- /*
- ** Try to get the path for successive components of the domain.
- ** Example for osgd.cb.att.uucp:
- ** osgd.cb.att
- ** cb.att
- ** att
- ** uucp ( remember stripping top level? )
- ** SMARTHOST
- ** Returns with error if we find no path.
- */
- for(step = 0; (step < domains); step++) {
- if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
- || (getpath(domainv[step] , path, cost) == EX_OK))/* no dot */
- break;
- }
-
- if(step == domains) {
- /*
- ** we've looked at each component of the domain without success
- */
- /*
- ** If domain is a UUCP address, look for a UUCP gateway.
- */
- if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
- /*
- ** The domain not is a UUCP address, or we can't
- ** find a UUCP gateway. If this is our last chance,
- ** look for a smarter host to deliver the mail.
- */
- if((look_smart == 0)
- || (getpath(SMARTHOST, path, cost) != EX_OK)) {
- /*
- ** All our efforts have been in vain.
- ** Tell them the bad news.
- */
- DEBUG("route '%s' failed\n", domain);
- return( EX_NOHOST );
- }
- }
- }
-
- route_complete:
-
- DEBUG("route: '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
-
- /*
- ** If we matched on the entire domain name, this address is fully resolved,
- ** and we plug <user> into it. If we matched on only part of the domain
- ** name, we plug <domain>!<user> in.
- */
- build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
- (void) sprintf(result, path, temp);
- return( EX_OK );
- }
- //E*O*F resolve.c//
-
- echo x - smail.prompt
- cat > "smail.prompt" << '//E*O*F smail.prompt//'
- #
- # @(#)smail.prompt 2.5 (smail) 9/15/87
- #
-
- loop=true
- while test $loop = true
- do
- case "$1" in
- string)
- echo "$2" 1>&2
- read ans
- if test ! -z "$ans"
- then
- echo $ans
- loop=false;
- fi
- ;;
- file)
- echo "$2" 1>&2
- read ans
- case "$ans" in
- /*)
- if test -f "$ans"
- then
- echo $ans
- loop=false;
- else
- echo "file '$ans' not found" 1>&2
- fi
- ;;
- *)
- echo "must give FULL PATH to file" 1>&2
- ;;
- esac
- ;;
- yesno)
- echo "$2" 1>&2
- read ans
- case "$ans" in
- y|Y|yes|Yes|YES)
- echo "yes"
- loop=false
- ;;
- n|N|no|No|NO)
- echo "no"
- loop=false
- ;;
- *)
- echo "Please enter yes or no" 1>&2
- ;;
- esac
- ;;
- *)
-
- echo "usage: $0 string|yesno prompt_message" 1>&2
- echo BOGUS_PROMPT_STRING
- loop=false
- ;;
- esac
- done
- //E*O*F smail.prompt//
-
- echo x - str.c
- cat > "str.c" << '//E*O*F str.c//'
- #ifndef lint
- static char *sccsid="@(#)str.c 2.5 (smail) 9/15/87";
- #endif
-
- #include "defs.h"
- #include <ctype.h>
-
- /*
- ** strncmpic: string compare, ignore case, stop after 'n' chars
- */
-
- strncmpic(s1, s2, n)
- char *s1, *s2;
- int n;
- {
- register char *u = s1;
- register char *p = s2;
-
- while((n > 0) && (*p != '\0')) {
- /* chars match or only case different */
- if(lower(*u) == lower(*p)) {
- p++; /* examine next char */
- u++;
- } else {
- break; /* no match - stop comparison */
- }
- n--;
- }
- if(n > 0) {
- return(lower(*u) - lower(*p)); /* return "difference" */
- } else {
- return(0);
- }
- }
-
- /*
- ** strcmpic: string compare, ignore case
- */
-
- strcmpic(s1, s2)
- char *s1, *s2;
- {
- register char *u = s1;
- register char *p = s2;
-
- while(*p != '\0') {
- /* chars match or only case different */
- if(lower(*u) == lower(*p)) {
- p++; /* examine next char */
- u++;
- } else {
- break; /* no match - stop comparison */
- }
- }
-
- return(lower(*u) - lower(*p)); /* return "difference" */
- }
-
- //E*O*F str.c//
-
- echo x - svbinmail.c
- cat > "svbinmail.c" << '//E*O*F svbinmail.c//'
- #ifndef lint
- static char *sccsid = "@(#)svbinmail.c 2.5 (smail) 9/15/87";
- #endif
- /* */
- /* This program will be used in place of /bin/mail on SVR2 sites.
- /* It looks at the arguments and decides whether to call
- /* SENDER for sending mail, or READER for reading mail.
- /*
- /* before installing as /bin/mail, move the stock /bin/mail to /bin/lmail
- /*
- /* */
-
- #include <stdio.h>
- #include "defs.h"
-
- #ifdef SENDMAIL
- #define SENDER SENDMAIL
- #else
- #define SENDER "/bin/rmail"
- #endif
-
- #define READER "/bin/lmail"
-
- #define TRUE 1
- #define FALSE 0
-
- char prog[128];
-
- void perror(), exit(), usage();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- extern int optind;
- extern char *optarg;
-
- int i, j, c;
- int reading, sending;
-
- reading = sending = FALSE;
-
- (void) strcpy(prog, argv[0]);
-
- if(argc == 1) {
- reading = TRUE;
- } else {
- while((c = getopt(argc, argv, "epqrtf:")) != EOF) {
- switch(c) {
- case 'e':
- case 'p':
- case 'q':
- case 'r':
- case 'f':
- reading = TRUE;
- break;
- case 't':
- sending = TRUE;
- break;
- default:
- usage();
- return(1);
- }
- }
- }
-
- /* any arguments left over -> sending */
- if(argc > optind) {
- sending = TRUE;
- }
-
- if((reading == TRUE) && (sending == TRUE)) {
- usage();
- return(1);
- }
-
- if(sending == TRUE) {
- argv[0] = SENDER;
- for(i = 1, j = optind; j < argc; i++, j++) {
- argv[i] = argv[j];
- }
- argv[i] = NULL;
- } else {
- argv[0] = READER;
- }
-
- (void) execvp(argv[0], argv);
- (void) fprintf(stderr, "%s: execvp(\"%s\", argv) failed: ",
- prog, argv[0]);
- perror("");
- return(1);
- }
-
- void
- usage()
- {
- (void) fprintf(stderr, "usage:\t%s [ -epqr ] [ -f file ]\n", prog);
- (void) fprintf(stderr, "\t%s [ -t ] persons\n", prog);
- }
- //E*O*F svbinmail.c//
-
- echo x - sysexits.h
- cat > "sysexits.h" << '//E*O*F sysexits.h//'
- /*
- ** @(#)sysexits.h 2.5 (smail) 9/15/87
- */
-
- # define EX_OK 0 /* successful termination */
- # define EX_USAGE 64 /* command line usage error */
- # define EX_NOHOST 68 /* host name unknown */
- # define EX_UNAVAILABLE 69 /* service unavailable */
- # define EX_SOFTWARE 70 /* internal software error */
- # define EX_OSFILE 72 /* critical OS file missing */
- # define EX_CANTCREAT 73 /* can't create (user) output file */
- # define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
- //E*O*F sysexits.h//
-
- echo x - template.cf
- cat > "template.cf" << '//E*O*F template.cf//'
- ############################################################
- #
- # SENDMAIL CONFIGURATION FILE
- #
- # supports internet style addressing
- # over UUCP and ethernet links.
- #
- # A product of the UUCP Project.
- #
- # @(#)template.cf 2.5 (smail) 9/15/87
- #
- ############################################################
-
-
- ############################################################
- #
- # Local configuration options - HINTS
- #
- # Host name and domain name macros.
- #
- # Dw sets $w
- # DD sets $D
- # CD sets $=D
- #
- # $D and $=D list all domains in which this host sits.
- # $D goes into outbound addresses, i.e. "user@$w.$D".
- # $A is another domain for which this host is 'authoritative'
- # it will will be turned into $D.
-
- CF_HOST
- CF_DOMAIN
- CF_AUTHORITY
- CF_DCLASS
-
- # Preemptive ether connections. We prefer these connections
- # over both designated transport mechanisms and the general depository.
- # You can add more classes (here and in S0).
-
- # /etc/hosts.smtp might be a link to /etc/hosts
- #
- CF_SMTP
-
- # Mock top-level domain names. These name designate a transport mechanism
- # and appear internally only, set in S3, used in S0, and removed in S4 and
- # (possibly) the ruleset for the particular mailer.
-
- CTETHER UUX
-
- # Relay host. Used at the end of S0 as the general depository for
- # addresses which didn't resolve locally.
-
- DRrelay
-
- #
- # End Local configuration options
- #
- ############################################################
-
- ############################################################
- #
- # General configuration information
- #
- ############################################################
-
- DVsmail2.5/CF_DATE
-
- ##########################
- # Special macros #
- ##########################
-
- # official hostname
- Dj$w.$D
- # my name
- DnMAILER-DAEMON
- # UNIX header format
- DlFrom $g $d
- # delimiter (operator) characters
- Do.:%@!^=/[]
- # format of a total name
- Dq$g$?x ($x)$.
- # SMTP login message
- De$j Sendmail $v/$V ready at $b
-
-
- ###################
- # Options #
- ###################
-
- # location of alias file
- OA/usr/lib/aliases
- # default delivery mode (deliver in background)
- Odbackground
- # (don't) connect to "expensive" mailers
- #Oc
- # temporary file mode
- OF0644
- # default GID
- Og1
- # location of help file
- OH/usr/lib/sendmail.hf
- # log level
- OL9
- # default messages to old style
- Oo
- # queue directory
- OQ/usr/spool/mqueue
- # read timeout -- violates protocols
- Or2h
- # status file
- OS/usr/lib/sendmail.st
- # queue up everything before starting transmission
- Os
- # default timeout interval
- OT3d
- # time zone names (V6 only)
- OtPST,PDT
- # default UID
- Ou1
- # wizard's password
- OWvoidpasswords
-
- ###############################
- # Message precedences #
- ###############################
-
- Pfirst-class=0
- Pspecial-delivery=100
- Pjunk=-100
-
- #########################
- # Trusted users #
- #########################
-
- Troot
- Tdaemon
- Tuucp
- Tnetwork
-
- #############################
- # Format of headers #
- #############################
-
- #H?P?Return-Path: <$g>
- HReceived: $?sfrom $s
- $.by $j ($v/$V)
- id $i; $b
- H?D?Resent-Date: $a
- H?D?Date: $a
- H?F?Resent-From: $q
- H?F?From: $q
- H?x?Full-Name: $x
- HSubject:
- # HPosted-Date: $a
- # H?l?Received-Date: $b
- H?M?Resent-Message-Id: <$t.$i@$j>
- H?M?Message-Id: <$t.$i@$j>
-
- ############################################################
- #
- # REWRITING RULES
- #
-
-
- ###########################
- # #
- # Name Canonicalization #
- # #
- ###########################
- S3
-
- # basic textual canonicalization
- R<> $@@ turn into magic token
- R$*<$+>$* $2 basic RFC821/822 parsing
- R$+ at $+ $1@$2 "at" -> "@" for RFC 822
- R$*<$*>$* $1$2$3 in case recursive
-
- # handle route-addr <@a,@b,@c:user@d>
- R@$+,$+ @$1:$2 change all "," to ":"
- R@$+:$+ $@<@$1>:$2 handle <route-addr>
- R$+:$*;@$+ $@$1:$2;@$3 list syntax
-
- # Rewrite address into a domain-based address. Any special mock domain names
- # (like UUX) should be defined on the CT line and removed (if necessary)
- # in S4. You can use them in S0 for designated transport mechanisms.
-
- # Delimiters with precedence over @. Add yours here.
-
- # The @ delimiter. Leave this alone.
- R$+@$+ $:$1<@$2> focus on domain
- R$+<$+@$+> $1$2<@$3> move gaze right
- R$+<@$+> $@$1<@$2> already canonical
-
- # Delimiters with precedence below @. Add yours here.
- R$+^$+ $1!$2 convert ^ to !
- R$-!$+ $@$2<@$1.UUX> resolve uucp names
- R$+.!$+ $@$2<@$1> domain.!host
- R$+!$+ $@$2<@$1> domain!host
-
- # % is a low precedence @.
- R$*%$* $@$>3$1@$2 %->@ and retry
-
- ############################################################
- #
- # RULESET ZERO PREAMBLE
- #
- ############################################################
-
- S0
-
- # first make canonical
- R$*<$*>$* $1$2$3 defocus
- R$+ $:$>3$1 make canonical
-
- # handle special cases.....
- R@ $#local$:MAILER-DAEMON handle <> form
- R$*<@[$+]>$* $#ether$@[$2]$:$1@[$2]$3 numeric internet spec
-
- # strip local stuff
- R$*<@$-.$w.$D>$* $1<@$2>$3 thishost.mydom
- CF_GATEWAYR$*<@$-.$D>$* $1<@$2>$3 mydom
- R$*<@$-.$w.$=D>$* $1<@$2>$4 thishost.anydom
- R$*<@$-.$w.$A>$* $1<@$2>$3 thishost.anotherdom
- R$*<@$-.$A>$* $1<@$2>$3 anotherdom
- R$*<@$-.$w.$=T>$* $1<@$2>$4 thishost.mockdom
- CF_GATEWAYR$*<$*$w>$* $1<$2>$3 thishost
- R$*<$*.>$* $1<$2>$3 drop trailing dot
- R<@>:$+ $@$>0$1 strip null route, retry
- R$+<@> $@$>0$1 strip null addr, retry
-
-
- ###############################################
- # Machine dependent part of ruleset zero #
- ###############################################
-
- # Preemption: for a host on a known link turn the domain spec into a
- # mock domain indicating the link. One set of these rules for each of
- # the F classes listed in the local configuration options.
-
- R$*<$*$=E.$D>$* $:$1<$2$3.ETHER>$4 etherhost.mydomain
- R$*<$*$=E.$=D>$* $:$1<$2$3.ETHER>$5 etherhost.anydomain
- R$*<$*$=E.$A>$* $:$1<$2$3.ETHER>$4 etherhost.anotherdomain
- R$*<$*$=E.$=T>$* $:$1<$2$3.ETHER>$5 etherhost.mock-domain
- R$*<$*$=E>$* $:$1<$2$3.ETHER>$4 etherhost
-
- # Designated delivery: use the indicated transport mechanism. One of
- # these rules for each of the mock domains defined in $=T. You can
- # remove these if you just want general disposition. HINTS.
-
- # Designated delivery:
- R$*<@$=U.UUX>$* $#uux$@$2$:$1$3 known uucphost
- R$*<@$=E$+.ETHER>$* $#ether$@$2$:$1@$2$4 known etherhost
- R$*<@$+.ETHER>$* $#ether$@$2$:$1@$2$3 etherhost
-
- # throw out mock domain name now
- R$*<$*.$=T>$* $1<$2>$4
-
- # General disposition of remote mail (comment out all but one). You
- # might add to this list, if you have other "smarter" mailers. HINTS.
-
- R$*<@$->:$+ $#uux$@$2$:$1$3 forward to $2
- R$*<@$*>$* $#uux$@$2$:$1$3 hand to uucp
- #R$*<@$*>$* $#uux$@$R$:$1@$2$3 hand to uucp relay
- #R$*<@$*>$* $#ether$@$R$:$1@$2$3 hand to ether relay
- #R$*<$*>$* $#error$:unknown address $1$2$3 don't hand anywhere
-
- # local delivery
- R$+ $#local$:$1 user
-
- ############################################################
- #
- # Local and Program Mailer specification
- #
- ############################################################
-
- CF_SVMAILMlocal, P=CF_LOCALMAIL, F=lsDFMhumSU, S=10, R=20, A=rmail $u
- CF_BSMAILMlocal, P=CF_LOCALMAIL, F=rlsDFMmn, S=10, R=20, A=mail -d $u
- Mprog, P=/bin/sh, F=lsDFMe, S=10, R=20, A=sh -c $u
-
- S10
- R@ MAILER-DAEMON errors to mailer-daemon
- CF_HIDDENHOSTSR$+<@$+.$j>$* $1<@$j>$3 hide anydom.$j under $j
-
- S20
-
- ############################################################
- #
- # UUCP Mailer specification
- #
- ############################################################
-
- Muux, P=/bin/smail, F=sDFMhum, S=14, R=24, M=100000,
- A=smail -vH$j $h!$u
-
- S14
- R$+<@$=E> $1 user@etherhost -> user
- R$*<@$+>$* $@$1<@$2>$3 already ok
- CF_HIDDENHOSTSR$+<@$+.$j>$* $1<@$j>$3 hide anydom.$j under $j
- R$+ $@$1<@$j> add our full address
-
- S24
-
- ############################################################
- #
- # SMTP ethernet mailer
- #
- ############################################################
-
- Mether, P=[IPC], F=msDFMuCXP, S=11, R=21, A=IPC $h
-
- S11
- R$*<@$+>$* $@$1<@$2>$3 already ok
- R$+ $@$1<@$w> add our hostname
-
- S21
-
- #################################
- # Final Output Post-rewriting #
- #################################
-
- # This rewrites the internal $=T mock domains into their external form.
- # The default is to replace the mock domain name with $D.
- # The last two lines are stock.
-
- S4
- R@ $@ handle <> error addr
- R$+<@$-.UUX> $2!$1 u@host.UUX => host!u
- R$*<$*$=T>$* $:$1<$2$D>$4 change local info
- R$*<$+>$* $1$2$3 defocus
- R@$+:$+:$+ @$1,$2:$3 <route-addr> canonical
- //E*O*F template.cf//
-
- exit 0
-