Path: seismo!harvard!talcott!panda!Jim Crammond From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: Sendmail UK-1.4 part 4 of 5 Message-ID: <1642@panda.UUCP> Date: 11 Apr 86 11:12:51 GMT Sender: jpn@panda.UUCP Lines: 1393 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 59 Submitted by: Jim Crammond # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. -----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Support # This archive created: Sat Mar 1 14:35:21 1986 echo shar: creating directory Support mkdir Support cd Support echo shar: extracting Makefile '(1208 characters)' cat << \SHAR_EOF > Makefile # # Makefile for assorted programs related to Sendmail. # # @(#)Makefile UK-1.4 sendmail configuartion 12/2/86 # CFLAGS=-O #CFLAGS=-O -Dvoid=int # some pdp11's need this # X25 flags: # Add -DYORKD2_2 if you have the D2.2 York code distribution X25FLAGS=-I/usr/src/local/x25/usr/src/ UUCPFLAGS=-I/usr/src/local/ukuucp/uucp/ UUCPLIB=/usr/src/local/ukuucp/uucp/uulib.a uucp: rmail muucp cp rmail /bin/rmail cp muucp /usr/lib/uucp/muucp chown uucp /usr/lib/uucp/muucp chgrp uucp /usr/lib/uucp/muucp chmod 6711 /usr/lib/uucp/muucp bitnet: damail bsmtp cp damail /usr/local/lib/rscs/damail cp bsmtp /usr/local/lib/rscs/bsmtp rmail: rmail.c cc $(CFLAGS) rmail.c -o rmail muucp: muucp.c cc $(CFLAGS) $(UUCPFLAGS) muucp.c $(UUCPLIB) -o muucp damail: damail.c cc $(CFLAGS) damail.c -o damail bsmtp: bsmtp.c cc $(CFLAGS) bsmtp.c -o bsmtp janet: mailer hhsend cp mailer /usr/lib/x25 chown root /usr/lib/x25/mailer chmod 755 /usr/lib/x25/mailer cp hhsend /usr/lib/x25 chown root /usr/lib/x25/hhsend chmod 4755 /usr/lib/x25/hhsend mailer: mailer.c dlit.o cc $(CFLAGS) $(X25FLAGS) mailer.c dlit.o -lx25 -o mailer hhsend: hhsend.c dlit.o cc $(CFLAGS) $(X25FLAGS) hhsend.c dlit.o -o hhsend SHAR_EOF if test 1208 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 1208 characters)' fi echo shar: extracting README '(2378 characters)' cat << \SHAR_EOF > README This directory contains some sendmail interface programs. Interfaces ---------- rmail.c: This is a rewrite of the standard uucp -> sendmail interface program which just a better job of deducing the From path from the uucp from line(s), and also sets sendmail's $s macro. This replaces /bin/rmail supplied with BSD4.2. muucp.c: This is a sendmail -> uucp interface program. This takes a message processed by sendmail and prepends a uucp From line then creates the appropriate uucp files. This replaces /usr/bin/uux for sending mail over uucp. damail.c: This is a rewrite of the bitnet -> sendmail interface program supplied with the Cornell version of the RSCS emulation package. This reads the from person from the From: line and sets sendmail's $s macro. This replaces /usr/local/lib/rscs/damail supplied with the RSCS software. bsmtp.c: This is a sendmail -> "batched smtp" interface program for use with the bitnet RSCS emulation package. It allows bitnet users to mail to people on other networks such as arpa and uucp. mailer.c: This is a janet -> sendmail interface program. This reads a message in JNT mail format and converts it into a form suitable for calling sendmail. This also sets sendmail's $s macro. This replaces /usr/lib/x25/mailer supplied with the York X25 software. hhsend.c: This is a sendmail -> janet interface program. This reads a message processed by sendmail and converts it into JNT mail format, then calls mhhcp to send it. This effectively replaces the /usr/lib/x25/hhmail supplied with the York X25 software; the standard mail user interfaces together with sendmail perform the other functions provided by hhmail. dlit.c: This contains routines used by the janet mailer interfaces, i.e. mailer.c and hhsend.c, to handle address/domain literal conversions. Dlit.c contains a table of network names, dnic numbers and gateway addresses to/from that network. This table is obviously host specific, thus the tables need to be edited before making the janet sendmail interfaces. Installation ------------ This directory contains a Makefile which should be able to create the various interface programs and install them in their expected places. By saying "make " the interfaces will be compiled and installed as appropriate for a given mailer. Of course, you need to be superuser to do this. SHAR_EOF if test 2378 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 2378 characters)' fi echo shar: extracting damail.c '(3233 characters)' cat << \SHAR_EOF > damail.c /* * rscs to sendmail mail interface * invoked by the rscs master control daemon when a file with filetype MAIL * is received over BITNET. * * The syntax is * damail * * * Bill Nesheim * Cornell U Dept of Computer Science * August, 1983 * * Rewritten by Jim Crammond * Weizmann Institute * Feb 1985 */ #include #include #include #include #include "../common/rscs.h" #include "../common/daemon.h" #define MAILLOG "/usr/lib/rscs/maillog" main(ac,av) int ac; char **av; { FILE *mail, *outfile, *log; char line[BUFSIZ], From[BUFSIZ], To[BUFSIZ]; char sender[20]; char *actime, *err; long tm, time(); int loc, smpid, ppe[2]; union wait status; if(ac < 2) { logerror("DAMAIL: No Mail File??"); return(TRUE); } if((log = fopen(MAILLOG, "a")) == (FILE *)NULL) { logerror("Can't open mail log file!"); return(FALSE); } if((mail = fopen(av[1],"r")) == (FILE *)NULL) { sprintf(line,"MTU: Can't open %s", av[1]); logerror(line); return(FALSE); } /* apparent source */ sprintf(From,"%s@%s.BITNET", av[3], av[2]); /* apparent destination */ sprintf(To,"%s@%s.BITNET", av[5], av[4]); /* sender flag to sendmail */ convlower(av[2]); sprintf(sender,"-oMs%s.bitnet", av[2]); /* try to find real destination and source */ while (fgets(line, BUFSIZ, mail) != NULL) { if (strncmp(line, "From:", 3) == 0) { register char *p, *e; char *index(); char *addr; p = line + 5; while (*p == ' ') p++; addr = p; if ( (p=index(addr, '<')) && (e=index(p, '>')) ) { /* * address of the form: comment
*/ addr = ++p; *e = '\0'; } else if ( (e=index(addr, '(')) ) { /* * address of the form: address (comment) */ while (*--e == ' ') ; *++e = '\0'; } else if ( (e=index(addr, '\n')) ) *++e = '\0'; strcpy(From, addr); break; } } rewind(mail); tm = time(0L); actime = (char *)ctime(&tm); actime[19] = '\000'; /* open pipe to sendmail */ pipe(ppe); if((smpid=vfork()) == 0) { close(0); dup(ppe[0], 0); execl("/usr/lib/sendmail", "sendmail", sender, "-odi", "-oem", "-f", From, To, 0); logerror("MTU: exec failed"); perror("reason"); _exit(1); } if((outfile = fdopen(ppe[1], "w")) == (FILE *)NULL) { logerror("MTU: pipe fdopen failure!"); return(FALSE); } loc = 1; while (fgets(line, BUFSIZ, mail) != NULL) { if (loc == 1) { loc++; if(strncmp(line, ":READ", 5) == 0) continue; } fputs(line, outfile); } fclose(outfile); fclose(mail); wait(&status); switch(status.w_retcode) { case EX_OK: err="sent"; break; case EX_NOUSER: err="no such user"; break; case EX_NOHOST: err="host unknown"; break; case EX_UNAVAILABLE: err="service unavailable"; break; default: err="other"; } fprintf(log,"%s Received mail from %s %s (tag %s %s) \n", actime, av[2], av[3], av[4], av[5]); fprintf(log,"\t%s (%d) %s (%d) from %s to %s\n", status.w_retcode ? "NOT SENT" : "Sent" , smpid, err, status.w_retcode, From, To); fclose(log); unlink(av[1]); return(status.w_retcode); } SHAR_EOF if test 3233 -ne "`wc -c damail.c`" then echo shar: error transmitting damail.c '(should have been 3233 characters)' fi echo shar: extracting dlit.c '(2250 characters)' cat << \SHAR_EOF > dlit.c /* * Domain literal handling. * This contains two routines to convert YBTS addresses to domain * literals, and vice versa. To do this, there is a table of * network names together with their DNIC numbers and gateway addresses * to that network (if not directly connected). * * Jim Crammond 10/85 */ #include #define MAXLEN 256 typedef struct { char *n_name; /* network name */ char *n_dnic; /* network id code */ char *n_gate; /* address to/from network gateway */ } net; /* * Host Dependent information. The DNIC identifies the network * after any gateway addresses have been stripped. (A zero length * DNIC will match all addresses.) A null gateway address indicates * a direct connection to the network. */ net nets[] = { "PSS", "2342", "00001500004000", "EDNET", "000015", 0, "EDNET", "000016", 0, "JANET", "0000", "00001500009900", 0, 0, 0, }; /* * addr_to_dlit -- converts a YBTS strings into a domain literal * * returns: domain literal, if successful * YBTS string otherwise */ char * addr_to_dlit(addr) char *addr; { static char dlit[MAXLEN]; register char *p; net *np; int len; for (np=nets; np->n_name; np++) { p = addr; if (np->n_gate) { /* match and skip gateway part of address */ len = strlen(np->n_gate); if (strncmp(p, np->n_gate, len) == 0) { p += len; if (*p != '.' && *p != '/') continue; p++; } else continue; } len = strlen(np->n_dnic); if (strncmp(p, np->n_dnic, len) == 0) { sprintf(dlit, "+%s.%s", np->n_name, p); return(dlit); } } return(addr); } /* * dlit_to_addr -- converts a domain literal into a YBTS string * * returns: YBTS string, if successful * domain literal otherwise */ char * dlit_to_addr(dlit) char *dlit; { static char addr[MAXLEN]; register char *p, *q; net *np; char pdn[20]; if (*dlit == '+') { for (p=dlit+1, q=pdn; *p && *p != '.'; p++, q++) *q = islower(*p) ? toupper(*p) : *p; *q = '\0'; p++; for (np=nets; np->n_name; np++) { if (strcmp(pdn, np->n_name) == 0) { if (np->n_gate) { /* prepend gateway addr */ sprintf(addr, "%s.%s", np->n_gate, p); return(addr); } return(p); } } } return(dlit); } SHAR_EOF if test 2250 -ne "`wc -c dlit.c`" then echo shar: error transmitting dlit.c '(should have been 2250 characters)' fi echo shar: extracting hhsend.c '(3110 characters)' cat << \SHAR_EOF > hhsend.c /* * hhsend - Sendmail -> JNT mailer interface. * * This program takes a hostname and a list of addresses to send to as * arguments and a mail message as standard input and creates a file * containing a Janet header followed by the mail message, then * calls mhhcp to send it over the network. * * Written by Jim Crammond. 4/85 * * Modified to interpret a hostname which is a domain literal * or a raw address enclosed in '[' ']'. Domain literal's are * converted to raw addresses before being passed to mhhcp. * * Jim Crammond & Scott Larnach 10/85 */ #include #include #include #include #include "local.h" #define MAILMODE (0660) /* mode of created spool file */ #ifdef DEBUG #undef SPOOLD #define SPOOLD "." #endif DEBUG FILE *mailf = NULL; char sfile[ sizeof(SPOOLD) + 14 ]; int delete(); char *index(); char *dlit_to_addr(); main(argc, argv) int argc; char *argv[]; { char *myname; char *host; char **users; int nusers; myname = argv[0]; if (argc < 3) { fprintf(stderr, "usage: %s host users...\n", myname); exit(EX_USAGE); } host = argv[1]; users = &argv[2]; nusers = argc - 2; /* catch signals */ signal(SIGHUP, delete); signal(SIGINT, delete); signal(SIGQUIT, delete); signal(SIGTERM, delete); /* send the mail */ sendmail(host, users, nusers); /* NOTREACHED */ } /* * sendmail - creates a mail file for mhhcp and exec mhhcp. */ sendmail(host, users, nusers) char *host; char *users[]; int nusers; { register char *auser, *p; char line[BUFSIZ]; union wait status; /* create spool file */ sprintf(sfile, "%s/M%06d", SPOOLD, getpid() ); mailf = fopen(sfile, "w"); if (mailf == NULL) { fprintf(stderr, "cannot create mail spool file %s\n", sfile); exit(EX_CANTCREAT); } chmod(sfile, MAILMODE); /* write out JNT-header */ while (nusers > 1) { auser = users[ --nusers ]; fprintf(mailf, "%s,\n", auser); } auser = users[0]; fprintf(mailf, "%s\n\n", auser); /* write out header + message from stdin (supplied by sendmail) */ while (fgets(line, sizeof(line), stdin) != NULL) fputs(line, mailf); fclose(mailf); /* handle domain literal */ if (*host == '[') { host++; /* strip [ ]'s */ for (p = host; *p != ']'; p++); *p = '\0'; host = dlit_to_addr(host); } #ifdef DEBUG fprintf(stderr,"call: %s %s %s\n", MHHCP, sfile, host); exit(0); #endif DEBUG switch (fork()) { case -1: unlink(sfile); exit(EX_TEMPFAIL); case 0: #ifdef YORKD2_2 /* no hhP logging by default now. Need -L flag */ execl(MHHCPPATH, MHHCP, "-L", sfile, host, 0); #else execl(MHHCPPATH, MHHCP, sfile, host, 0); #endif unlink(sfile); exit(EX_UNAVAILABLE); default: wait(&status); #ifdef YORKD2_2 if (status.w_retcode == 0) #else if (status.w_retcode == 1) #endif exit(EX_OK); else { unlink(sfile); exit(EX_NOHOST); } } } /* * delete - delete mail file and exit. Called on any interrupt. */ delete() { if (mailf != NULL) { fclose(mailf); unlink(sfile); } exit(EX_TEMPFAIL); } SHAR_EOF if test 3110 -ne "`wc -c hhsend.c`" then echo shar: error transmitting hhsend.c '(should have been 3110 characters)' fi echo shar: extracting mailer.c '(3804 characters)' cat << \SHAR_EOF > mailer.c /* * mailer - JNT -> Sendmail interface. * * This program takes a mail file in JNT format and converts the * Janet header into an argument and then calls sendmail giving the * message part of the mail file as standard input. * * Written by Jim Crammond. 4/85 * * Fixed to send failed mail to postmaster. * Jim Reid 6/85 * * Improved handling of received YBTS addresses * Jim Crammond & Scott Larnach 7/85 * * Fixed format of domain literal to conform with * Greybook/NRS. Jim Crammond & Scott Larnach 9/85 */ #include #include #include #include #include #include "local.h" struct tdirent *gettdnam(), *td; #define CMDSIZ 5000 /* command line size */ #define SENDMAIL "/usr/lib/sendmail" /* sendmail rah rah */ /* #define CATCHALL /* send all undeliverable mail to postmaster */ char cmd[CMDSIZ]; char line[BUFSIZ]; char *file, *via; FILE *fopen(), *popen(); FILE *fp, *outp, *logfd; long iop, time(); char *ctime(); char *rindex(); char *addr_to_dlit(); int LOGGING; main(argc, argv) int argc; char *argv[]; { register char *usersp, *c, *n; char *f; int ret; #ifndef DEBUG chdir(SPOOLD); /* somewhere to dump core */ #endif if ((logfd = fopen(MAIL_LOG, "a")) == NULL) LOGGING = 0; else LOGGING = 1; chmod(MAIL_LOG, 0666); time(&iop); LOG("\n\nMail server started %s", ctime(&iop)); file = argv[1]; via = argv[2]; if ((fp = fopen(file, "r")) == NULL) { LOG("could not open %s\n", file); done(); } /* * find out where this came from. * Strip the trailing FTP.MAIL, and pass the rest to gettdnam. */ for (f = via; *f; f++) { if (*f == '/' || *f == '.') { if (strcmp(f+1, MAILADR) == 0) { *f = '\0'; break; /* reached the FTP.MAIL bit */ } } } /* * initialise command sendmail command line. * The sender macro is either set to the name returned by * gettdnam, or a domain literal returned by addr_to_dlit */ if ((td = gettdnam(via, 0)) != 0) sprintf(cmd, "%s -ba -oMs%s", SENDMAIL, td->td_name); else sprintf(cmd, "%s -ba -oMs[%s]", SENDMAIL, addr_to_dlit(via)); usersp = cmd; while (*usersp != '\0') usersp++; /* * get list of addresses to send to in JNT-header form and * convert to a list of command line arguments. */ while (fgets(line, BUFSIZ, fp) != NULL) { c = line; while (*c == ' ' || *c == '\t') c++; if (*c == '\n') break; *usersp++ = ' '; while (*c != '\0' && *c != '\n') { if (*c == ',') { *usersp++ = ' '; c++; } else if (*c == '@' && *(c+1) == '[') { /* strip domain literals */ while (*++c) { if (*c == ']') { c++; break; } } } else *usersp++ = *c++; } } *usersp = '\0'; /* call sendmail */ #ifdef DEBUG fprintf(stderr, "call: %s\n", cmd); done(); #endif DEBUG LOG("%s\n", cmd); outp = popen(cmd, "w"); while (fgets(line, sizeof(line), fp) != NULL) fputs(line, outp); ret = pclose(outp); #ifdef CATCHALL if (ret & 0xffff) #else if (ret & 0xff) #endif { /* * sendmail failed - send to postmaster */ LOG("%s failed, returning status %d\n", cmd, ret); error_mail(); exit(EX_OSERR); } LOG("exit status %d\n", ret >> 8); done(); } /* * Send garbaged mail to postmaster */ error_mail() { FILE *efp; if ((efp = popen("/bin/mail postmaster", "w")) != NULL) { fprintf(efp, "Mail from %s failed\n", via); fprintf(efp, "Command line was: %s\n", cmd); fprintf(efp, "Message body follows:\n"); rewind(fp); while (fgets(line, sizeof(line), fp) != NULL) fputs(line, efp); pclose(efp); } } /* VARARGS1 */ LOG(fmt, args) char *fmt; { if (LOGGING) { fprintf(logfd, fmt, args); fflush(logfd); } return; } done() { unlink(file); exit(EX_OK); } SHAR_EOF if test 3804 -ne "`wc -c mailer.c`" then echo shar: error transmitting mailer.c '(should have been 3804 characters)' fi echo shar: extracting muucp.c '(6688 characters)' cat << \SHAR_EOF > muucp.c /* * Send mail over uucp, using the UUCP Transmission Format * usage: muucp [ -f ] [ -H ] host user1 user2 .... */ /* * "X" files use local system name, avoids conflict. Steve Bellovin */ #include "uucp.h" #include #define GENSEND(f, a, b, c, d, e) {\ fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e);\ } main(argc, argv) char *argv[]; { char cfile[NAMESIZE]; /* send commands for files from here */ char dfile[NAMESIZE]; /* used for all data files from here */ char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ char tfile[NAMESIZE]; /* temporary file name */ char tcfile[NAMESIZE]; /* temporary file name */ int cflag = 0; /* commands in C. file flag */ int rflag = 0; /* C. files for receiving flag */ char buf[BUFSIZ]; int startjob = 1; char Grade = 'A'; char path[MAXFULLNAME]; char cmd[BUFSIZ]; char *ap, *cmdp; char *xsys, local[8]; char *rfname, *From; char *perc_to_uucp(), *tidy_addr(); FILE *fprx, *fpc, *fpd; extern FILE *ufopen(); time_t now; extern time_t time(); extern char *ctime(); int ret; #ifdef SYSINFO /* UKfix 021: LMCL. Gather accounting info. (Orig by Piet Beertema) */ char *fromsys; char *fromper; extern char *getenv(); char locsys = 0; long xfersize; #endif SYSINFO int orig_uid = getuid(); strcpy(Progname, "muucp"); uucpname(Myname); guinfo(orig_uid, User, path); From = User; rfname = Myname; umask(WFMASK); Ofn = 1; Ifn = 0; while (argc>1 && argv[1][0] == '-') { switch(argv[1][1]){ case 'f': From = &argv[1][2]; break; case 'H': if (argv[1][2] != '\0') rfname = &argv[1][2]; break; case 'r': startjob = 0; break; case 'g': Grade = argv[1][2]; break; case 'x': chkdebug(orig_uid); Debug = atoi(&argv[1][2]); if (Debug <= 0) Debug = 1; break; default: fprintf(stderr, "unknown flag %s\n", argv[1]); break; } --argc; argv++; } DEBUG(4, "\n\n** %s **\n", "START"); /* find remote system name (argv[1]) */ xsys = *++argv; sprintf(Rmtname, "%.7s", mapname(xsys)); strcpy(xsys, Rmtname); /* Now ensure they're the same! */ DEBUG(4, "xsys %s\n", xsys); if (versys(xsys) != 0) { /* bad system name */ fprintf(stderr, "bad system name: %s\n", xsys); cleanup(EX_NOHOST); } #ifdef SYSINFO /* UKfix 021: LMCL. Allow for host groups. */ if (!(locsys = islocal( xsys )) && *exthost) { /* is this a local system? */ strcpy(local, exthost); } else #endif SYSINFO sprintf(local, "%.7s", Myname); subchdir(Spool); gename(DATAPRE, local, 'X', rxfile); fprx = ufopen(rxfile, "w"); ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0); gename(DATAPRE, local, 'T', tcfile); fpc = ufopen(tcfile, "w"); ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0); fprintf(fprx, "%c %s %s\n", X_USER, User, local); gename(DATAPRE, local, 'B', dfile); fpd = ufopen(dfile, "w"); ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); /* generate the UUCP From line */ From = perc_to_uucp(From); From = tidy_addr(From); if (From == NULL) From = User; DEBUG(4, "from %s\n", From); time(&now); fprintf(fpd, "From %s %.24s remote from %s\n", From, ctime(&now), rfname); #ifdef SYSINFO /* account for everything */ xfersize = 44 + strlen(From) + strlen(rfname); #endif SYSINFO /* read in stdin (mail message) */ while (!feof(stdin)) { ret = fread(buf, 1, BUFSIZ, stdin); fwrite(buf, 1, ret, fpd); #ifdef SYSINFO /* UKfix 021: LMCL. tot up size of data to xfer */ xfersize += ret; #endif SYSINFO } fclose(fpd); if (strcmp(local, xsys) != SAME) { GENSEND(fpc, dfile, dfile, User, "", dfile); cflag++; } fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); fprintf(fprx, "%c %s\n", X_STDIN, dfile); strcpy(cmd, "rmail "); cmdp = cmd + 6; for (++argv, --argc; argc > 1; argc--) { ap = *argv++; while (*ap) *cmdp++ = *ap++; *cmdp++ = ' '; } *cmdp = '\0'; DEBUG(4, "cmd - %s\n", cmd); fprintf(fprx, "%c %s\n", X_CMD, cmd); #ifdef SYSINFO /* UKfix 021: LMCL. Export accountable site/user * (Orig by Piet Beertema). */ if ((fromsys = getenv("ACCTSYS")) != NULL) fprintf(fprx, "%c %s\n", X_ACCTSYS, fromsys); else if( !locsys && *exthost ) fprintf(fprx, "%c %s\n", X_ACCTSYS, exthost); if ((fromper = getenv("ACCTPER")) != NULL) fprintf(fprx, "%c %s\n", X_ACCTPER, fromper ); /* For mail you record the senders address */ fprintf(fprx, "%c %ld %s\n", X_ACCTSZ, xfersize, From ); #endif SYSINFO logent(cmd, "XQT QUE'D"); fclose(fprx); strcpy(tfile, rxfile); tfile[0] = XQTPRE; tfile[ strlen(tfile) - 5 ] = Grade; /* UKfix 006 */ if (strcmp(xsys, local) == SAME) { /* rti!trt: xmv() works across filesystems, link(II) doesnt */ xmv(rxfile, tfile); if (startjob) if (rflag) xuucico(xsys); else xuuxqt(); } else { GENSEND(fpc, rxfile, tfile, User, "", rxfile); cflag++; } fclose(fpc); if (cflag) { gename(CMDPRE, xsys, Grade, cfile); /* rti!trt: use xmv() rather than link(II) */ xmv(tcfile, cfile); if (startjob) xuucico(xsys); cleanup(EX_OK); } else unlink(subfile(tcfile)); } #define FTABSIZE 30 char Fname[FTABSIZE][NAMESIZE]; int Fnamect = 0; /*** * cleanup - cleanup and unlink if error * * return - none - do exit() */ cleanup(code) int code; { int i; logcls(); rmlock(CNULL); if (code) { for (i = 0; i < Fnamect; i++) unlink(subfile(Fname[i])); fprintf(stderr, "%s failed. code %d\n", Progname, code); } DEBUG(1, "exit code %d\n", code); exit(code); } /*** * ufopen - open file and record name * * return file pointer. */ FILE *ufopen(file, mode) char *file, *mode; { if (Fnamect < FTABSIZE) strcpy(Fname[Fnamect++], file); else logent("Fname", "TABLE OVERFLOW"); return(fopen(subfile(file), mode)); } /* ** PERC_TO_UUCP -- converts an address in Percent style into uucp style ** ** e.g. user%c.bitnet%b.arpa@a.uucp -> a.uucp!b.arpa!c.bitnet!user */ char * perc_to_uucp(addr) char *addr; { static char buf[512]; char *bp = buf; char *p; DEBUG(6, "perc_to_uucp(%s) ", addr); while ((p = rindex(addr,'@')) != NULL || (p = rindex(addr,'%')) != NULL) { *p++ = '\0'; while (*p) *bp++ = *p++; *bp++ = '!'; } strcpy(bp, addr); DEBUG(6, "returns %s\n", buf); return(buf); } /* ** TIDY_ADDR -- strips duplicate domain names from start of address ** ** e.g. cs.hw.AC.UK!cs.hw.AC.UK!jim -> cs.hw.AC.UK!jim */ char * tidy_addr(addr) char *addr; { register char *p, *q; DEBUG(6, "tidy_addr(%s) ", addr); p = addr; while ((q = index(p, '!')) != NULL) { ++q; while (*p != '!' && *p == *q) { p++; q++; } if (*p != '!' && *q != '!') break; addr = ++p; } DEBUG(6, "returns %s\n", addr); return(addr); } SHAR_EOF if test 6688 -ne "`wc -c muucp.c`" then echo shar: error transmitting muucp.c '(should have been 6688 characters)' fi echo shar: extracting bsmtp.c '(1226 characters)' cat << \SHAR_EOF > bsmtp.c /* * sendmail to "batch smtp" mail interface. * Generates an smtp format message for sending, as a message body, to * to special mailboxes at arpa/uucp bitnet gateways for forwarding on to * other networks. * * Usage is * bsmtp ... */ #include #include #define VMCOPY "/usr/bin/vmcopy" main(argc, argv) int argc; char *argv[]; { char buf[BUFSIZ], cmd[256]; FILE *outp, *popen(); int ret, i; if (argc < 5) { fprintf(stderr, "usage: %s smtpuser mydomain sender addr...\n", argv[0]); exit(EX_USAGE); } sprintf(cmd, "%s %s class=M fname=MAILER ftype=MAIL width=80 device=PUNCH\n", VMCOPY, argv[1]); outp = popen(cmd, "w"); fprintf(outp, "HELO %s\nTICK %d\nVERB ON\nMAIL From:<%s>\n", argv[2], getpid(), argv[3]); while (argc > 4) { fprintf(outp, "RCPT To:<%s>\n", argv[4]); argv++; argc--; } fprintf(outp, "DATA\n"); while (!feof(stdin)) { ret = fread(buf, 1, BUFSIZ, stdin); fwrite(buf, 1, ret, outp); } fprintf(outp, ".\nQUIT\n"); i = pclose(outp); /* check for errors */ if ((i & 0377) != 0) { fprintf(stderr, "pclose: status 0%o\n", i); exit(EX_OSERR); } exit((i >> 8) & 0377); } SHAR_EOF if test 1226 -ne "`wc -c bsmtp.c`" then echo shar: error transmitting bsmtp.c '(should have been 1226 characters)' fi echo shar: extracting rmail.c '(3831 characters)' cat << \SHAR_EOF > rmail.c #ifndef lint static char sccsid[] = "@(#)rmail.c 4.4 (Berkeley) 8/11/83"; #endif /* ** RMAIL -- UUCP mail server. ** ** This program reads the >From ... remote from ... lines that ** UUCP is so fond of and turns them into something reasonable. ** It calls sendmail giving it a -f option built from these ** lines. ** ** Modified to set the sender's hostname (deduced from first ** "remote from host" line) and convert the final "user" part ** from an address with '@' and '%' (which mmdf is so fond of) ** in to a 'pure' uucp address. -Jim Crammond, (hwcs!jim) 29/11/84 */ # include # include typedef char bool; #define TRUE 1 #define FALSE 0 extern FILE *popen(); extern char *index(); extern char *rindex(); char *perc_to_uucp(); bool Debug; # define MAILER "/usr/lib/sendmail" main(argc, argv) char **argv; { FILE *out; /* output to sendmail */ char lbuf[512]; /* one line of the message */ char from[512]; /* accumulated path of sender */ char ufrom[128]; /* user on remote system */ char sys[64]; /* a system in path */ char sysname[64]; /* system received from */ char cmd[2000]; register char *cp; register char *uf; /* ptr into ufrom */ int linecount; int i; # ifdef DEBUG if (argc > 1 && strcmp(argv[1], "-T") == 0) { Debug = TRUE; argc--; argv++; } # endif DEBUG if (argc < 2) { fprintf(stderr, "Usage: rmail user ...\n"); exit(EX_USAGE); } (void) strcpy(from, ""); (void) strcpy(sysname, ""); (void) strcpy(ufrom, "/dev/null"); linecount = 0; while (fgets(lbuf, sizeof lbuf, stdin) != NULL) { if (strncmp(lbuf, "From ", 5) != 0 && strncmp(lbuf, ">From ", 6) != 0) break; linecount++; (void) sscanf(lbuf, "%*s %s", ufrom); cp = lbuf; uf = ufrom; while ((cp = index(cp, 'r')) != NULL) { #ifdef DEBUG if (Debug) printf("cp='%s'\n", cp); #endif if (sscanf(cp, "remote from %s", sys) == 1) { (void) strcat(from, sys); (void) strcat(from, "!"); if (linecount == 1) (void) strcpy(sysname, sys); break; } cp++; } #ifdef DEBUG if (Debug) printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from); #endif } /* * check for percent style addresses in user field */ if (index(uf, '@') != NULL || index(uf, '%') != NULL) uf = perc_to_uucp(uf); /* * if this is a new style "From domain!user .. remote from system" * header then don't prepend the system name to the from person */ if (linecount == 1 && (cp = index(uf, '!')) != NULL) { char *p = index(uf, '.'); if (p != NULL && p < cp) (void) strcpy(from, uf); else (void) strcat(from, uf); } else (void) strcat(from, uf); (void) sprintf(cmd, "%s -em -f%s", MAILER, from); if (*sysname != '\0') { (void) strcat(cmd, " -oMs"); (void) strcat(cmd, sysname); } while (*++argv != NULL) { (void) strcat(cmd, " '"); if (**argv == '(') (void) strncat(cmd, *argv + 1, strlen(*argv) - 2); else (void) strcat(cmd, *argv); (void) strcat(cmd, "'"); } #ifdef DEBUG if (Debug) printf("cmd='%s'\n", cmd); #endif out = popen(cmd, "w"); fputs(lbuf, out); while (fgets(lbuf, sizeof lbuf, stdin)) fputs(lbuf, out); i = pclose(out); if ((i & 0377) != 0) { fprintf(stderr, "pclose: status 0%o\n", i); exit(EX_OSERR); } exit((i >> 8) & 0377); } /* ** PERC_TO_UUCP -- converts an address in Percent style into uucp style ** ** e.g. user%c.bitnet%b.arpa@a.uucp -> a.uucp!b.arpa!c.bitnet!user */ char * perc_to_uucp(addr) char *addr; { static char buf[512]; char *bp = buf; char *p; #ifdef DEBUG if (Debug) printf("perc_to_uucp(%s) ", addr); #endif while ((p = rindex(addr,'@')) != NULL || (p = rindex(addr,'%')) != NULL) { *p++ = '\0'; while (*p) *bp++ = *p++; *bp++ = '!'; } strcpy(bp, addr); #ifdef DEBUG printf("returns %s\n", buf); #endif return(buf); } SHAR_EOF if test 3831 -ne "`wc -c rmail.c`" then echo shar: error transmitting rmail.c '(should have been 3831 characters)' fi echo shar: done with directory Support cd .. # End of shell archive exit 0