Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (06/28/90)
Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon> Posting-number: Volume 90, Issue 188 Archive-name: unix/uucp-1.06d/part10 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 10 (of 12)." # Contents: uucp2/src/sendmail/sendmail.c # Wrapped by tadguy@xanth on Thu Jun 28 08:21:35 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'uucp2/src/sendmail/sendmail.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/sendmail/sendmail.c'\" else echo shar: Extracting \"'uucp2/src/sendmail/sendmail.c'\" \(24049 characters\) sed "s/^X//" >'uucp2/src/sendmail/sendmail.c' <<'END_OF_FILE' X X/* X * SENDMAIL / RMAIL X * X * $Header: Beta:src/uucp/src/sendmail/RCS/sendmail.c,v 1.1 90/02/02 12:15:01 dillon Exp Locker: dillon $ X * X * (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved. X * X * SENDMAIL <file -f from -t to -s subject -c cc -b bcc -r X * RMAIL user X * X * Example: Sendmail <datafile -froot X * X * From: line is automatically added but can be overriden by a From: X * header in the file. stdin is made up of a list of headers, a blank X * line, and then data until EOF. X * X * the -r option tells sendmail that this is incomming mail. X * If av[0] begins with an 'r' for RMail instead of an 's' for X * Sendmail, then the rmail argument format is used (rmail user), X * as well as forcing -r. X */ X X#include "defs.h" X X#include <fcntl.h> X#include <log.h> X#include <time.h> X#include <pwd.h> X Xtypedef struct List LIST; Xtypedef struct Node NODE; X XIDENT(".06"); X XLocal void Usage(void); XLocal int brk(void); XLocal NODE *MakeNode(LIST *, char *); XLocal void MakeToFixNode(LIST *, char *, char *); XLocal void fixCallBack(char *); XLocal void IntegrateHeader(char *, short); XLocal void FromFixup(LIST *); XLocal void ToFixup(LIST *); XLocal void MakeToAddrNode(LIST *, char *); XLocal FILE *SendMailTo(LIST *, FILE *); XLocal FILE *OneMailTo(char *, FILE *); XLocal FILE *OneMailToPipe(char *, FILE *); XLocal FILE *OneMailToUser(char *, FILE *); XLocal FILE *OneMailToFile(char *, FILE *); XLocal FILE *OneMailToUUCP(char *, char *, FILE *); XLocal void DumpHeaderInfo(FILE *, int, int, int); XLocal void DumpHeader(FILE *, char *, LIST *); XLocal NODE *FindHeader(char *); XLocal void DumpCombineHeader(FILE *, char *, LIST *); XLocal char *atime(time_t *); XLocal int GetHourOffset(char *); XLocal void PostPend(char *, int); XLocal int EmptyList(LIST *); X X X#define RCVR_UUCP 1 X#define RCVR_SENDMAIL 2 X Xchar *UserName; Xchar *RealName; Xchar *NodeName; Xchar *DomainName; Xchar *TimeZoneName; /* All caps, ex: PST */ Xchar *DefaultNode; /* for addr formats we don't understand */ XLIST RecvList; /* Received: */ XLIST FromList; /* last one rules */ XLIST ToList; /* To: */ XLIST CcList; /* Cc: */ XLIST BccList; /* Bcc: */ XLIST XccList; /* list of actual mail to be sent */ XLIST SubjList; /* Subject: */ XLIST HdrList; /* other headers not specifically parsed */ Xchar ScrBuf[1024]; Xchar ScrBuf2[1024]; Xchar TempFileBuf[256]; Xint Seq; /* UUCP sequence no */ Xchar Notify; Xchar ROpt; /* Receive-Mail flag */ Xstatic char OrigFromLine[512]; Xstatic char FromLine[512]; /* 'From ' line, if ROpt */ X X X Xmain(ac, av) Xchar *av[]; X{ X short isRMail = 0; X short isSendMail = 1; X FILE *fi; X X onbreak(brk); X X NewList(&RecvList); X NewList(&FromList); X NewList(&ToList); X NewList(&CcList); X NewList(&BccList); X NewList(&XccList); X NewList(&SubjList); X NewList(&HdrList); X X UserName = GetUserName(); X RealName = GetRealName(); X X if (UserName == NULL) { X puts("Sendmail: UserName config entry not found!"); X ulog(0, "UserName config missing"); X exit(1); X } X if (RealName == NULL) { X puts("Sendmail: RealName config entry not found!"); X ulog(0, "RealName config missing"); X exit(1); X } X X NodeName = FindConfig("NodeName"); X if (NodeName == NULL) { X puts("Sendmail: NodeName config entry not found!"); X ulog(0, "NodeName config missing"); X exit(1); X } X DomainName = FindConfig("DomainName"); X if (DomainName == NULL) { X puts("Sendmail: DomainName config entry not found! using .UUCP"); X DomainName = ".UUCP"; X } X DefaultNode = FindConfig("DefaultNode"); X TimeZoneName = FindConfig("TimeZone"); X X LoadAliases(); X X { X char *ptr = av[0] + strlen(av[0]); X X /* X * Skip path X */ X X while (ptr >= av[0] && *ptr != ':' && *ptr != '/') X --ptr; X ++ptr; X X if (*ptr == 'r' || *ptr == 'R') { X isRMail = 1; X isSendMail = 0; X } X } X X if (isRMail) { X char *addr = (ac == 2) ? av[1] : "Mailer-Daemon"; X X MakeNode(&BccList, addr); X UserName = "postmaster"; /* XXX */ X RealName = "Mr.Amiga"; /* XXX */ X ROpt = 1; /* no header processing */ X } X if (isSendMail) { X short i; X char *arg; X for (i = 1; i < ac; ++i) { X arg = av[i]; X if (*arg != '-') X Usage(); X switch(arg[1]) { X case 'f': X UserName = av[i+1]; X sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName); X MakeNode(&FromList, ScrBuf); X ++i; X break; X case 'r': X RealName = av[++i]; X break; X case 't': X MakeNode(&ToList, av[++i]); X break; X case 'c': X MakeNode(&CcList, av[++i]); X break; X case 'b': X MakeNode(&BccList, av[++i]); X break; X case 's': X MakeNode(&SubjList, av[++i]); X break; X case 'r': X ++ROpt; X break; X default: X Usage(); X } X } X } X X /* X * Read headers from input file. Headers are not necessarily X * contained on a single line. Maximum 4096 chars per header. X */ X X if (ROpt) { X fgets(ScrBuf, sizeof(ScrBuf), stdin); X strcpy(OrigFromLine, ScrBuf); X if (strncmp(ScrBuf, "From ", 5) != 0) { X ulog(-1, "Receive mail, expected 'From ', got %s", ScrBuf); X } X strcpy(FromLine, "From "); X PostPend(ScrBuf + 5, 1); X X while (fgets(ScrBuf, sizeof(ScrBuf), stdin) && strncmp(ScrBuf, ">From ", 6) == 0) { X strcpy(OrigFromLine, ScrBuf + 1); X PostPend(ScrBuf + 6, 1); X } X strcpy(ScrBuf2, OrigFromLine + 5); X PostPend(ScrBuf2, 0); X } else { X ScrBuf[0] = '\n'; X fgets(ScrBuf, sizeof(ScrBuf), stdin); X } X { X static char Hdr[4096]; X short i = 0; /* index into Hdr */ X X while (ScrBuf[0] != '\n') { X char *ptr = ScrBuf; X while (*ptr && *ptr != ' ' && *ptr != 9 && *ptr != ':') X ++ptr; X if (*ptr == ':') { /* found new header */ X if (i) /* Dump old header */ X IntegrateHeader(Hdr, i); X strcpy(Hdr, ScrBuf); X i = strlen(Hdr); X } else { /* append to existing header */ X if (i == 0) X puts("Expected a Header!"); X strcpy(Hdr + i, ScrBuf); X i = i + strlen(Hdr + i); X } X X if (fgets(ScrBuf, sizeof(ScrBuf), stdin) == NULL) X ScrBuf[0] = '\n'; X } X if (i) X IntegrateHeader(Hdr, i); X X if (ScrBuf[0] != '\n') { X puts("sendmail: no mail"); X ulog(0, "No Mail"); X exit(1); X } X } X X /* X * Parse & fixup each To:, Cc:, and Bcc: field. X * X * From: we add the personal info arg from the password file X * To: we expand any aliases X */ X X if (ROpt == 0) X FromFixup(&FromList); X if (ROpt) { X ToFixup(&BccList); X } else { X ToFixup(&ToList); X ToFixup(&CcList); X ToFixup(&BccList); X } X X /* X * If no Subject: field add a dummy one X */ X X if (EmptyList(&SubjList)) X MakeNode(&SubjList, ""); X X if (EmptyList(&FromList)) { X sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName); X MakeNode(&FromList, ScrBuf); X } X X fi = SendMailTo(&XccList, stdin); X if (fi && fi != stdin) X fclose(fi); X if (TempFileBuf[0]) X remove(TempFileBuf); X UnLockFiles(); X X /* X * Notify if T:MailRdy does not exist (created by us, deleted by X * notify when notify exits). Prevents running multiple notifies. X */ X X if (Notify) { X int fd = open("T:MailRdy", O_RDONLY); X if (fd < 0) { X char *cmd; X X X if (cmd = FindConfig(MAILREADYCMD)) { X fd = open("T:MailRdy", O_CREAT|O_TRUNC, 0666); X if (fd >= 0) X close(fd); X sprintf(ScrBuf, "Run %s -x T:MailRdy", cmd); X Execute(ScrBuf, NULL, NULL); X } X } else { X close(fd); X } X } X return(0); X} X Xvoid XUsage() X{ X printf( X "Sendmail -f user [-t address -c address -b address -s subject -r]\n" X "RMail user\n" X ); X} X Xint Xbrk() X{ X return(0); X} X X/* X * Strips string and creates named node which is appended to the X * given list. X */ X XNODE * XMakeNode(list, str) XLIST *list; Xchar *str; X{ X NODE *node; X char *ptr; X X while (*str == ' ' || *str == 9) X ++str; X for (ptr = str + strlen(str); ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr); X ++ptr; X *ptr = 0; X node = malloc(sizeof(NODE) + strlen(str) + 1); X node->ln_Name = (char *)(node + 1); X strcpy(node->ln_Name, str); X AddTail(list, node); X return(node); X} X X/* X * X */ X Xvoid XMakeToFixNode(list, str, send) XLIST *list; Xchar *str; Xchar *send; X{ X char *ptr; X short len; X short c; X void fixCallBack(); X X while (str < send && (*str == ' ' || *str == 9)) X ++str; X for (ptr = send - 1; ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr); X ++ptr; X X len = ptr - str; X if (len < 0) X return; X X /* X * str[0..len-1] X */ X X c = str[len]; X str[len] = 0; X X if (ROpt) { /* disallow remote asking for special options */ X ulog(-1, "Received mail for %s", str); X if (str[0] == '>' || str[0] == '<' || str[0] == '|' || str[0] == ':' || str[0] == '/') { X ulog(-1, "SendMail, bad user %s", str); X return; X } X } X X { X NODE *node = malloc(sizeof(NODE) + strlen(str) + 1); X X node->ln_Name = (char *)(node + 1); X strcpy(node->ln_Name, str); X AddTail(list, node); X } X X UserAliasList(str, fixCallBack); /* from lib/alias.c */ X str[len] = c; X} X Xvoid XfixCallBack(user) Xchar *user; X{ X NODE *node; X X if (user[0] == '<') { X FILE *fi = fopen(user + 1, "r"); X char *buf = malloc(256); X X if (fi == NULL) { X ulog(-1, "Unable to open < file %s", user + 1); X return; X } X while (fgets(buf, 256, fi)) { X short i = 0; X short j; X while (buf[i] == ' ' || buf[i] == 9) X ++i; X if (buf[i] == 0 || buf[i] == '\n') X continue; X for (j = i; buf[j] && buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9; ++j); X buf[j] = 0; X UserAliasList(buf, fixCallBack); X } X fclose(fi); X free(buf); X return; X } X X ulog(-1, "Sendmail, Sending mail to %s", user); X X if (user[0] == '\\') X ++user; X X node = malloc(sizeof(NODE) + strlen(user) + 1); X node->ln_Name = (char *)(node + 1); X strcpy(node->ln_Name, user); X AddTail(&XccList, node); X} X X X/* X * Integrates a header X */ X Xvoid XIntegrateHeader(hdr, len) Xchar *hdr; Xshort len; X{ X if (hdr[len-1] == '\n') /* strip trailing newline */ X hdr[len-1] = 0; X X if (strncmp(hdr, "From:", 5) == 0) { X MakeNode(&FromList, hdr + 5); X return; X } X if (strncmp(hdr, "To:", 3) == 0) { X MakeNode(&ToList, hdr + 3); X return; X } X if (strncmp(hdr, "Cc:", 3) == 0) { X MakeNode(&CcList, hdr + 3); X return; X } X if (strncmp(hdr, "Bcc:", 4) == 0) { X MakeNode(&BccList, hdr + 4); X return; X } X if (strncmp(hdr, "Subject:", 8) == 0) { X MakeNode(&SubjList, hdr + 8); X return; X } X if (strncmp(hdr, "Received:", 9) == 0) { X MakeNode(&RecvList, hdr + 9); X return; X } X MakeNode(&HdrList, hdr); X} X X/* X * Adds (personal info) to FromList based on passwd entry or, if X * that is not available, from the Config entry 'RealName' or X * ENV:REALNAME (env:REALNAME takes precedence) X */ X Xvoid XFromFixup(list) XLIST *list; X{ X NODE *node; X NODE *nn; X LIST tmpList; X X NewList(&tmpList); X X while (node = RemHead(list)) { X /* X * FIXME. Fix getpwnam() and use pw_gecos entry. X */ X nn = malloc(sizeof(NODE) + strlen(node->ln_Name) + strlen(RealName) + 16); X nn->ln_Name = (char *)(nn + 1); X sprintf(nn->ln_Name, "%s (%s)", node->ln_Name, RealName); X free(node); X AddTail(&tmpList, nn); X } X while (node = RemHead(&tmpList)) X AddTail(list, node); X} X X/* X * Converts an unparsed list of names into a list of single address X * fields, removing any personal idents from the entries. These will X * be recombined after processing when the data file is written out. X * X * Also expands sendmail aliases (UULIB:Aliases) (HACK) X */ X Xvoid XToFixup(list) XLIST *list; X{ X NODE *node; X LIST tmpList; X X NewList(&tmpList); X X while (node = RemHead(list)) { X char *str = node->ln_Name; X char *ptr; X X while (*str) { /* breakup fields by newline or comma */ X for (ptr = str; *ptr && *ptr != '\n' && *ptr != ','; ++ptr); X MakeToAddrNode(&tmpList, str); X str = ptr; X while (*str == '\n' || *str == ',' || *str == ' ' || *str == 9) X ++str; X } X free(node); X } X while (node = RemHead(&tmpList)) X AddTail(list, node); X} X X/* X * Extracts a single name / address (comma or newline delimited) X * field and creates a new node. X */ X Xvoid XMakeToAddrNode(list, str) XLIST *list; Xchar *str; X{ X char *p1, *p2; X short ns = 0; /* non-whitespace encountered */ X X for (p1 = str; *p1 && *p1 != ',' && *p1 != '\n'; ++p1) { X if (*p1 == '(') { /* addr (name) OR (name) addr */ X if (ns) { /* addr (name) */ X MakeToFixNode(list, str, p1); X } else { X while (*p1 && *p1 != ',' && *p1 != '\n' && *p1 != ')') X ++p1; X if (*p1 == ')') { X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n'; ++p2); X MakeToFixNode(list, p1 + 1, p2); X } X } X return; X } X X if (*p1 == '<') { /* <addr> */ X for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n' && *p2 != '>'; ++p2); X if (*p2 == '>') X MakeToFixNode(list, p1 + 1, p2); X return; X } X if (*p1 != ' ' && *p1 != 9) X ns = 1; X } X MakeToFixNode(list, str, p1); X} X X X/* X * Send mail to <recipeant> X * X * -Local mail X * -Machine path (UUCP) X */ X XFILE * XSendMailTo(list, fi) XLIST *list; XFILE *fi; X{ X NODE *node; X X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) X fi = OneMailTo(node->ln_Name, fi); X return(fi); X} X XFILE * XOneMailTo(toaddr, rfi) Xchar *toaddr; XFILE *rfi; X{ X short i; X char c; X static char ToAddr[512]; X static char Buf[512]; X static char typeBuf[16]; X static char classBuf[16]; X static char addrBuf[128]; X X if (toaddr[0] == '|') /* pipe through command */ X return(OneMailToPipe(toaddr + 1, rfi)); X if (toaddr[0] == '>') /* copy to file */ X return(OneMailToFile(toaddr + 1, rfi)); X X strncpy(ToAddr, toaddr, sizeof(ToAddr)); X ToAddr[sizeof(ToAddr) - 1] = 0; X Xloop: X for (i = 0; c = ToAddr[i]; ++i) { X if (c == '!' || c == '%' || c == '@' || c == ':') X break; X } X if (c == 0) /* local name */ X return(OneMailToUser(ToAddr, rfi)); X X /* X * Non-Local mail X */ X X i = ParseAddress(ToAddr, Buf, strlen(ToAddr)); X if (DomainLookup(Buf, strlen(Buf), typeBuf, classBuf, addrBuf)) { X printf("type %s class %s addr %s\n", typeBuf, classBuf, addrBuf); X printf("buf %s\n", Buf); X X /* X * Note distinction between mail destination and mail forwarder. X * mail destination removes the first machine from the rmail line X * mail forwarder does NOT X */ X X if (strcmpi(classBuf, "UU") == 0) { X if (strcmpi(typeBuf, "MD") == 0) X return(OneMailToUUCP(addrBuf, Buf + i + 1, rfi)); X else X return(OneMailToUUCP(addrBuf, Buf, rfi)); X } else if (strcmpi(classBuf, "LL") == 0) { /* local mail, loop */ X for (i = 0; Buf[i] && Buf[i] != '!'; ++i); X if (Buf[i] == 0) { X strcpy(Buf + i, "postmaster"); X --i; X } X strcpy(ToAddr, Buf + i + 1); X goto loop; X } else { X ulog(-1, "Unsupported domain class: %s", classBuf); X printf("Unsupported domain class: %s\n", classBuf); X } X return(rfi); X } else { X ulog(-1, "Could not find domain for %s, no mail sent", Buf); X printf("Unable to send mail to %s\n", Buf); X return(rfi); X } X} X X XFILE * XOneMailToPipe(toaddr, rfi) Xchar *toaddr; XFILE *rfi; X{ X FILE *fi; X char *ptr; X static long pos; X X if (TempFileBuf[0] == 0) { X strcpy(TempFileBuf, TmpFileName("T:pipe")); X fi = fopen(TempFileBuf, "w"); X if (fi == NULL) { X ulog(-1, "Unable to open temp file %s for command: %s", TempFileBuf, toaddr); X return(rfi); X } X DumpHeaderInfo(fi, RCVR_SENDMAIL, 0, 1); X pos = ftell(fi); X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) X fputs(ScrBuf, fi); X fclose(fi); X } X strcpy(ScrBuf, toaddr); X X ptr = toaddr; X if (strncmpi(toaddr, "run", 3) == 0) { X ptr += 3; X while (*ptr == ' ' || *ptr == 9) X ++ptr; X } X while (*ptr && *ptr != ' ' && *ptr != 9) X ++ptr; X X if (*ptr == 0) X strcat(ScrBuf, " "); X sprintf(ScrBuf + (ptr - toaddr + 1), "<%s %s", TempFileBuf, ptr); X if (Execute(ScrBuf, NULL, NULL) == 0) X ulog(-1, "Couldn't execute %s", ScrBuf); X X fi = fopen(TempFileBuf, "r"); X if (fi) { X if (rfi != stdin) X fclose(rfi); X rfi = fi; X fseek(rfi, pos, 0); X } else { X ulog(-1, "Couldn't reopen temp '%s', mail failed!", TempFileBuf); X rfi = stdin; X } X return(rfi); X} X XFILE * XOneMailToUser(toaddr, rfi) Xchar *toaddr; XFILE *rfi; X{ X ++Notify; X strcpy(ScrBuf, MakeConfigPath(UUMAIL, toaddr)); X return(OneMailToFile(ScrBuf, rfi)); X} X XFILE * XOneMailToFile(tofile, rfi) Xchar *tofile; XFILE *rfi; X{ X FILE *fo; X static char DataFile[128]; X long pos; X X strcpy(DataFile, tofile); X X LockFile(DataFile); X fo = fopen(DataFile, "a"); X if (fo == NULL) { X strcpy(DataFile, "T:MailOverflow"); X fo = fopen(DataFile, "a"); X if (fo) X ulog(-1, "Could not append to %s, appending to %s", tofile, DataFile); X else X ulog(-1, "Can't append to anywhere! (%s)", tofile); X } X if (fo) { X DumpHeaderInfo(fo, RCVR_SENDMAIL, 0, 1); X pos = ftell(fo); X if (ROpt) { X if (fgets(ScrBuf, sizeof(ScrBuf), rfi)) X fputs(ScrBuf, fo); X } X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) { X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0) X strins(ScrBuf, " "); X fputs(ScrBuf, fo); X } X fclose(fo); X if (rfi != stdin) X fclose(rfi); X rfi = fopen(DataFile, "r"); X fseek(rfi, pos, 0); X } X UnLockFile(DataFile); X return(rfi); X} X XFILE * XOneMailToUUCP(toaddr, skipaddr, rfi) Xchar *toaddr; Xchar *skipaddr; XFILE *rfi; X{ X static char ExecFile[128]; X static char XExecFile[128]; X static char CommandFile[128]; X static char DataFile[128]; X static char DestNode[256]; X /*static char ToAddr[256];*/ X FILE *fi; X int seq; X long pos; X short i; X short ai; X char *spoolDir = strdup(MakeConfigPath(UUSPOOL, "")); X X /* X * If the destination node X */ X X strcpy(DestNode, toaddr); X X ai = -1; X for (i = 0; DestNode[i]; ++i) { X /* X * Remember index for additional paths X */ X X if (DestNode[i] == '!') { X DestNode[i] = 0; X ai = i + 1; X break; X } X X /* X * Cut off machine name at 7 chars and ignore any domain X * info. X */ X X if (i == 7 || DestNode[i] == '.') X DestNode[i] = 0; X } X X Seq = seq = GetSequence(4); X X#define FOFF strlen(spoolDir) X X sprintf(ExecFile, "%sD.%sX%04d", spoolDir, DestNode, seq++); X sprintf(XExecFile, "%sX.%sX%04d", spoolDir, DestNode, seq++); X sprintf(CommandFile,"%sC.%sA%04d", spoolDir, DestNode, seq++); X sprintf(DataFile, "%sD.%sB%04d", spoolDir, DestNode, seq); X X LockFile(CommandFile); X LockFile(DataFile); X X /* X * Note, cannot run uuxqt from sendmail as uuxqt may call X * sendmail! X */ X X if (strncmp(DestNode, NodeName, 7) == 0) X fi = fopen(XExecFile, "w"); X else X fi = fopen(ExecFile, "w"); X X if (fi == NULL) X goto fail; X X fprintf(fi, "U %s\n", UserName); X fprintf(fi, "F %s\n", DataFile + FOFF); X fprintf(fi, "I %s\n", DataFile + FOFF); X if (ai >= 0) X fprintf(fi, "C rmail %s!%s\n", DestNode + ai, skipaddr); X else X fprintf(fi, "C rmail %s\n", skipaddr); X fclose(fi); X X if (strncmp(DestNode, NodeName, 7)) { X fi = fopen(CommandFile, "w"); X if (fi == NULL) X goto fail; X X fprintf(fi, "S %s %s %s - %s 0666\n", DataFile + FOFF, DataFile + FOFF, UserName, DataFile + FOFF); X fprintf(fi, "S %s %s %s - %s 0666\n", ExecFile + FOFF, XExecFile + FOFF, UserName, ExecFile + FOFF); X fclose(fi); X } X X fi = fopen(DataFile, "w"); X if (fi == NULL) X goto fail; X X DumpHeaderInfo(fi, RCVR_UUCP, 1, 0); X pos = ftell(fi); X X if (ROpt) { X if (fgets(ScrBuf, sizeof(ScrBuf), rfi)) X fputs(ScrBuf, fi); X } X while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) { X if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0) X strins(ScrBuf, " "); X fputs(ScrBuf, fi); X } X fclose(fi); X if (rfi != stdin) X fclose(rfi); X fi = fopen(DataFile, "r"); X fseek(fi, pos, 0); X X UnLockFile(CommandFile); X UnLockFile(DataFile); X X free(spoolDir); X X return(fi); Xfail: X UnLockFile(CommandFile); X UnLockFile(DataFile); X X free(spoolDir); X puts("Fail"); X ulog(-1, "Output failed %s", CommandFile); X return(rfi); X} X Xvoid XDumpHeaderInfo(fi, rcvr, resend, local) XFILE *fi; Xint rcvr, resend, local; X{ X char *source; X time_t t; X X time(&t); X X /* X * Write header info X */ X X if (rcvr == RCVR_UUCP) X source = "AmigaUUCP"; X else X source = "Sendmail"; X X if (ROpt) { X if (resend) X fprintf(fi, "%s %s remote from %s\n", FromLine, atime(&t), NodeName); X else X fprintf(fi, "%s %s\n", FromLine, atime(&t)); X } else { X if (local) X fprintf(fi, "From %s %s\n", UserName, atime(&t)); X else X fprintf(fi, "From %s %s remote from %s\n", UserName, atime(&t), NodeName); X } X fprintf(fi, "Received: by %s%s (1.05D/Amiga)\n\tid AA%05d; %s\n", X NodeName, DomainName, Seq, atime(&t) X ); X DumpHeader(fi, "Received:", &RecvList); X if (ROpt == 0) { X time_t t2 = t + 3600 * GetHourOffset(TimeZoneName); X struct tm *ut; X X if (FindHeader("Date:") == NULL) X fprintf(fi, "Date: %s\n", atime(&t)); X ut = localtime(&t2); X fprintf(fi, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@%s%s>\n", X ut->tm_year % 100, ut->tm_mon + 1, ut->tm_mday, ut->tm_hour, ut->tm_min, X Seq, NodeName, DomainName X ); X } X X /* X * From:, To:, Cc:, Subject: (Bcc: never written to header), X * and any other header fields X */ X X DumpHeader(fi, NULL, &HdrList); X DumpHeader(fi, "From:", &FromList); X DumpCombineHeader(fi, "To:", &ToList); X if (!EmptyList(&CcList)) X DumpCombineHeader(fi, "Cc:", &CcList); X DumpHeader(fi, "Subject:", &SubjList); X X fprintf(fi, "\n"); X} X Xvoid XDumpHeader(fi, field, list) XFILE *fi; Xchar *field; XLIST *list; X{ X NODE *node; X X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) { X if (field) X fprintf(fi, "%s %s\n", field, node->ln_Name); X else X fprintf(fi, "%s\n", node->ln_Name); X } X} X XNODE * XFindHeader(field) Xchar *field; X{ X NODE *node; X short len = strlen(field); X X for (node = HdrList.lh_Head; node != (NODE *)&HdrList.lh_Tail; node = node->ln_Succ) { X if (strncmp(node->ln_Name, field, len) == 0) X return(node); X } X return(NULL); X} X Xvoid XDumpCombineHeader(fi, field, list) XFILE *fi; Xchar *field; XLIST *list; X{ X NODE *node; X short ci = 0; X X fprintf(fi, "%s ", field); X for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) { X if (ci && ci + strlen(node->ln_Name) > 70) { X fprintf(fi, ",\n\t"); X ci = 0; X } X if (ci) X fprintf(fi, ", "); X fprintf(fi, "%s", node->ln_Name); X ci += strlen(node->ln_Name) + 2; X } X fprintf(fi, "\n"); X} X Xchar * Xatime(pt) Xtime_t *pt; X{ X static char buf[40]; X static char *mo[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" X }; X static char *dow[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; X struct tm *ut = localtime(pt); X X sprintf(buf, "%s, %d %s %02d %02d:%02d:%02d %s", X dow[ut->tm_wday], ut->tm_mday, mo[ut->tm_mon], X ut->tm_year % 100, ut->tm_hour, ut->tm_min, ut->tm_sec, X TimeZoneName X ); X return(buf); X} X Xint XGetHourOffset(tz) Xchar *tz; X{ X short i; X X static struct { X char *Name; X short Hours; X } TZAry[] = { X "GMT", 0, X "UT", 0, X "PST", 8, X "MST", 7, X "CST", 6, X "EST", 5, X "AST", 4, X "PDT", 7, X "MDT", 6, X "CDT", 5, X "EDT", 4, X "ADT", 3, X NULL, 0 X }; X for (i = 0; TZAry[i].Name; ++i) { X if (strncmp(tz, TZAry[i].Name, 3) == 0) X return((int)TZAry[i].Hours); X } X ulog(-1, "Unknown Timezone: %s", tz); X printf("Unknown Timezone: %s", tz); X return(6); X} X Xvoid XPostPend(str, frend) Xchar *str; Xint frend; X{ X char *ptr; X if (frend) { X ptr = str + strlen(str); X while (ptr > str && *ptr != ' ' && *ptr != 9) { X if (*ptr == '\n') X *ptr = 0; X --ptr; X } X str = ptr + 1; X } X for (ptr = str; *ptr && *ptr != ' ' && *ptr != 9 && *ptr != '\n'; ++ptr); X if (frend) X *ptr++ = '!'; X *ptr = 0; X for (ptr = FromLine + 5; *ptr && *ptr != ' ' && *ptr != 9; ++ptr); X strins(ptr, str); X} X XEmptyList(list) XLIST *list; X{ X if (list->lh_Head == (NODE *)&list->lh_Tail) X return(1); X return(0); X} X END_OF_FILE if test 24049 -ne `wc -c <'uucp2/src/sendmail/sendmail.c'`; then echo shar: \"'uucp2/src/sendmail/sendmail.c'\" unpacked with wrong size! fi # end of 'uucp2/src/sendmail/sendmail.c' fi echo shar: End of archive 10 \(of 12\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.