|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 26395 (0x671b) Types: TextFile Names: »rmail.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/uucp/rmail.c«
/* rmail.c: */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/uucp/RCS/rmail.c,v 5.0 90/09/20 15:55:26 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/uucp/RCS/rmail.c,v 5.0 90/09/20 15:55:26 pp Exp Locker: pp $ * * $Log: rmail.c,v $ * Revision 5.0 90/09/20 15:55:26 pp * rcsforce : 5.0 public release * */ /* * R M A I L . C * * Developed from the Berkeley mail program of the same name * by Mike Obrien at RAND to run with the MMDF mail system. * Rewritten by Doug Kingston, US Army Ballistics Research Laboratory * Hacked a lot by Steve Bellovin (smb@unc) * * This program runs SETUID to Opr so that it can set effective and * real [ug]ids to mmdflogin. * * Steve Kille - Aug 84 * Take machete to it. Use protocol mode, * and always go thru submit - phew * Lee McLoughlin Oct 84. * Address munges some header lines into 822 format. * Peter Collinson Dec 85. * Lee's version was dependent on * (a) the uucp channel * (b) the domain tables associated with the uucp channel * This version costs more cycles (but there is generally * only one of these running on a machine at a time) and * uses mmdf's tables to dis-assemble bang routes converting * them into a domain address. * Peter Cowen Sept 89 * PP'ised * Julian Onions July 90 * Choked to death on it! * Piete Brooks June 90 * converted ! recipient addresses to % and @ */ #undef RUNALON #include "util.h" #include "head.h" #include "q.h" #include "prm.h" #include "ap.h" #include "adr.h" #include "chan.h" #include "retcode.h" #include <pwd.h> #include <signal.h> #include <sys/stat.h> #include <varargs.h> #define VERSION "3.0" #define NAMESZ 256 /* Limit on component name size. * LMCL was 64 */ #define ungetline(s) ((void) strcpy (tmpline,s),usetmp=1) #define MAXADRS 6 /* Max no. of adrs to output on a * single line. */ char debug; extern char *loc_dom_site, *pplogin, *supportaddr, *hdr_822_bp, *ia5_bp, *cont_822; extern char *index (); extern char *rindex (); extern char *getenv (); /* get the Accounting system from * the environment */ extern char *strdup (); extern char *malloc (); extern char *compress (); FILE *rm_msgf; /* temporary out for message text */ CHAN *chanptr; int Tmpmode = 0600; char Msgtmp[LINESIZE]; char rm_date[LINESIZE]; /* date of origination from uucp * header */ char rm_from[LINESIZE]; /* accumulated path of sender */ char origsys[NAMESZ]; /* originating system */ char origpath[LINESIZE]; /* path from us to originating * system */ char Mailsys[LINESIZE]; /* Mail system signature */ char tmpline[LINESIZE]; /* Temporary buffer for * continuations and such */ char usetmp = 0; /* Wether tmpline should be used */ char linebuf[LINESIZE]; /* scratchpad */ char nextdoor[LINESIZE]; /* The site nextdoor who sent the * mail */ char uchan[LINESIZE]; /* Channel to use for submission */ main (argc, argv) char **argv; int argc; { char fromwhom[NAMESZ]; /* user on remote system */ char *fromptr; char sys[NAMESZ]; /* an element in the uucp path */ char *cp, *d; struct passwd *pw, *getpwnam (), *getpwuid (); int fd; sys_init (argv[0]); if (argc > 2 && strcmp (argv[1], "-d") == 0) { debug = 1; argc--; argv++; } if (argc < 2) { fprintf (stderr, "Usage: rmail user [user ...]\n"); exit (1); } umask (0); /* * First, change effective and real UID/GID into Mailsys * owner */ if ((pw = getpwnam (pplogin)) == NULL) { fprintf (stderr, "Cannot find pplogin\n"); exit (99); } setgid (pw->pw_gid); setuid (pw->pw_uid); (void) sprintf (Mailsys, "<%s@%s>", pplogin, loc_dom_site); /* Create temp file for body of message */ (void) strcpy (Msgtmp, "/tmp/rmail.XXXXXX"); mktemp (Msgtmp); if ((fd = creat (Msgtmp, Tmpmode)) < 0) bomb ("Can't create %s\n", Msgtmp); close (fd); if ((rm_msgf = fopen (Msgtmp, "r+")) == NULL) bomb ("Can't reopen %s\n", Msgtmp); unlink (Msgtmp); /* * Unravell the From and >From lines at the head of the * message to work who sent it, the path it took to get * here and when it was sent. Some or all of this info may * be ignore depending on the 822 header info given. */ for (;;) { if (fgets (linebuf, sizeof linebuf, stdin) == NULL) break; if (strncmp (linebuf, "From ", 5) && strncmp (linebuf, ">From ", 6)) break; cp = index (linebuf, ' '); /* start of name */ fromptr = ++cp; cp = index (cp, ' '); /* cp at end of name */ *cp++ = 0; /* term. name, cp at date */ (void) strcpy (fromwhom, fromptr); while (isspace (*cp)) cp++; /* Skip any ws */ /* * The date is the rest of the line ending at \0 or * remote */ d = rm_date; while (*cp && strncmp (cp, " remote from ", 13)) *d++ = *cp++; *d = '\0'; for (;;) { cp = index (cp + 1, 'r'); if (cp == NULL) { cp = rindex (fromwhom, '!'); if (cp != NULL) { char *p; *cp = '\0'; p = rindex (fromwhom, '!'); if (p != NULL) (void) strcpy (origsys, p + 1); else (void) strcpy (origsys, fromwhom); (void) strcat (rm_from, fromwhom); (void) strcat (rm_from, "!"); (void) strcpy (fromwhom, cp + 1); goto out; } /* * Nothing coherent found - so look * in environment for ACCTSYS */ if ((cp = getenv ("ACCTSYS")) && *cp) { (void) strcpy (origsys, cp); (void) strcat (rm_from, cp); (void) strcat (rm_from, "!"); goto out; } strcpy(cp = sys, "remote from somewhere"); } if (strncmp (cp, "remote from ", 12) == 0) break; } sscanf (cp, "remote from %s", sys); (void) strcat (rm_from, sys); (void) strcpy (origsys, sys); /* Save for quick ref. */ (void) strcat (rm_from, "!"); out: ; } if (fromwhom[0] == '\0')/* No from line, illegal */ bomb ("%s", "No 'from' lines in message\n"); ungetline (linebuf); /* Complete the from field */ (void) strcat (rm_from, fromwhom); /* * A uk special - see if the first two components of the * constructed bang address are in fact the same site. * If so replace by their official name */ domain_cross (rm_from); /* * Save a copy of the path to the original site. This is * all the the path we were given - the user name after the * last !. NOTE: We keep the trailing !, hence the +1. */ (void) strcpy (origpath, rm_from); *(rindex (origpath, '!') + 1) = '\0'; /* Savepath is given a copy of the immediate neighbour */ if ((d = index (rm_from, '!')) != NULL) { *d = '\0'; (void) strcpy (nextdoor, rm_from); *d = '!'; } else (void) strcpy (nextdoor, rm_from); /* find the channel depending in the nextdoor site */ set_channel (nextdoor); /* Convert the from to Arpa format and leave it in from */ fromcvt (rm_from, fromwhom); (void) strcpy (rm_from, fromwhom); if (debug) printf ("from=%s, origpath=%s, date=%s\n", rm_from, origpath, rm_date); msgfix (rm_from, rm_date); exit (xsubmit (rm_from, argv, argc)); } /* * Munge the message header. * All header lines with addresses in are munged into 822 format. * If no "From:" line is given supply one based on the UUCP Froms, do the * same if no "Date:". */ typedef struct { char *hname; int hfound; } Hdrselect; Hdrselect hdrselect[] = { "date", 0, /* this is a little naughty - we * need */ /* to register that we have had this */ /* but not address munge it */ /* so it has token 0 */ "from", 0, "to", 0, "cc", 0, "bcc", 0, "sender", 0, "reply-to", 0, "resent-from", 0, "resent-sender", 0, "resent-to", 0, 0, 0 #define HDATE 0 #define HFROM 1 #define HTO 2 #define HCC 3 #define HBCC 4 #define HSENDER 5 #define HREPLY 6 #define HRFROM 7 #define HRSENDER 8 #define HRTO 9 }; /* Is this header in the list of those to have their addresses munged? */ /* return header value offset value */ /* notice that it returns 0 for the date header */ shouldmunge (name) char *name; { register Hdrselect *h; if (debug) printf ("in shouldmunge with %s\n", name); for (h = hdrselect; h->hname != NULL; h++) if (!lexequ (h->hname, name)) { h->hfound++; return (h - hdrselect); } return (0); } /* If this is a header line then grab the name of the header and stuff it * into name then return a pointer to the actually body of the line. * Otherwise return NULL. * NOTE: A header is a line that begins with a word formed of alphanums and * dashes (-) then possibly some whitespace then a colon (:). */ char * grabheader (s, name) register char *s, *name; { char tmpbuf[LINESIZE]; /* Copy the name into name */ while (isalpha (*s) || isdigit (*s) || *s == '-') *name++ = *s++; *name = '\0'; /* Skip any whitespace */ while (isspace (*s)) s++; /* This is a header if the next char is colon */ if (*s == ':') { s++; /* * This is probably illegal but we fail horribly if * it happens - so we will guard against it */ if (*s != ' ' && *s != '\t' && *s != '\0') { /* we need to add a * space */ (void) strcpy (tmpbuf, s); (void) sprintf (s, " %s", tmpbuf); } return (s); /* Return a pointer to the rest of * the line */ } else return (NULL); } msgfix (from, date) char *from, *date; { register char *s; char *rest; char *lkp; char name[LINESIZE]; char tmpbuf[LINESIZE]; int haveheader = 0; /* Do I have a header? */ int headertoken; char *grabline (); /* Loop through all the headers */ while (1) { if (debug) printf ("in msgfix about to grabline\n"); s = grabline (); if (debug) printf ("got %s", s); /* Is this the end of the header? */ if (*s == '\0' || *s == '\n' || feof (stdin)) break; /* Is this a continuation line? */ if (haveheader && isspace (*s)) { /* * Note: Address munged headers handled * specially */ fputs (s, rm_msgf); } else { /* Grab the header name from the line */ if ((rest = grabheader (s, name)) == NULL) /* * Not a header therefore all * headers done */ break; haveheader = 1; /* Should I address munge this? */ if (headertoken = shouldmunge (name)) { char *finalstr; finalstr = "\n"; fprintf (rm_msgf, "%s: ", name); /* * deal specially with From lines * the parser loses comments so we * retain them specially here */ if (headertoken == HFROM || headertoken == HRFROM) { if (lkp = index (rest, '<')) { *lkp = '\0'; if (*rest == ' ') fprintf (rm_msgf, "%s<", rest + 1); else fprintf (rm_msgf, "%s<", rest); *lkp = '<'; finalstr = ">\n"; (void) strcpy (tmpbuf, lkp); /* * notice that we * copy from the < * * /* to start with * a space */ tmpbuf[0] = ' '; rest = tmpbuf; lkp = rindex (rest, '>'); if (lkp) *lkp = '\0'; } if (lkp = index (rest, '(')) { *lkp = '\0'; (void) sprintf (tmpbuf, " (%s\n", lkp + 1); finalstr = tmpbuf; } } hadr_munge (rest); fputs (finalstr, rm_msgf); } else fputs (s, rm_msgf); } } /* No From: line was given, create one based on the From's */ if (hdrselect[HFROM].hfound == 0) { fprintf (rm_msgf, "From: %s", from); } /* No Date: line was given, create one based on the From's */ if (hdrselect[HDATE].hfound == 0) { datecvt (date, tmpbuf); /* Convert from uucp -> * Arpa */ fprintf (rm_msgf, "Date: %s\n", tmpbuf); } /* Copy the rest of the file, if there is any more */ if (!feof (stdin)) { /* * If the first line of the message isn't blank * output the blank separator line. */ if (*s) putc ('\n', rm_msgf); do { fputs (s, rm_msgf); s = grabline (); } while (!feof (stdin)); } } char * grabline () { if (debug) printf ("in grabline "); /* * Grab the next line. Remembering this might be the * tmpline */ if (usetmp) { if (debug) printf ("using tmpline "); (void) strcpy (linebuf, tmpline); usetmp = 0; } else fgets (linebuf, sizeof linebuf, stdin); /* Anything wrong? */ if (ferror (stdin)) fputs ("\n *** Problem during receipt from UUCP ***\n", rm_msgf); if (debug) printf ("returning %s\n ", linebuf); return (linebuf); } char *next = NULL; /* Where nextchar gets the next * char from */ char adrs[LINESIZE]; /* Partly munged addresses go here */ nextchar () { register char *s; /* scratch pointer. */ if (next != NULL && *next != '\0') { if (debug) printf ("<%c>", *next); return (*next++); } /* The last buffer is now empty, fill 'er up */ next = grabline (); if (feof (stdin) || !isspace (*next) || *next == '\0') { /* * Yipee! We've reached the end of the address * list. */ ungetline (next); next = NULL; /* Force it to read buffer */ return (-1); } /* Zap excess whitespace */ compress (next, adrs); /* * This may be a slightly duff list generated by some of * the UNIX mailers eg: "x y z" rather than "x,y,z" If it * is in this ^^^^^^^ convert to ^^^^^^^ NOTE: This won't * handle list: "x<x@y> y<y@z>" conversions! */ if (index (adrs, ' ') != NULL && index (adrs, ',') == NULL && index (adrs, '<') == NULL && index (adrs, '(') == NULL && index (adrs, '"') == NULL) { for (s = adrs; *s; s++) if (*s == ' ') *s = ','; } next = adrs; /* * This a continuation line so return in a seperator just * in case */ return (','); } /* Munge and address list thats part of a header line. * Try and get the ap_* (MMDF) routines to do as much as possible for * us. */ hadr_munge (list) char *list; { AP_ptr the_addr; /* ---> THE ADDRESS <--- */ int adrsout = 0; /* How many address have been * output */ ungetline (list); while (1) { AP_ptr ap_pinit (); the_addr = ap_pinit (nextchar); if (the_addr == (AP_ptr) NOTOK) bomb ("%s", "cannot initialise address parser!"); ap_clear (); switch (ap_1adr ()) { case NOTOK: /* Something went wrong!! */ ap_sqdelete (the_addr, (AP_ptr) 0); ap_free (the_addr); /* * Emergency action in case of parser break * down: print out the rest of the line (I * hope). */ fprintf (rm_msgf, "%s", tmpline); continue; case OK: /* I've got an address to output! */ /* * output a comma seperator between the * addresses and a newline every once in a * while to make sure the lines aren't too * long */ if (adrsout++) fprintf (rm_msgf, ",%s ", adrsout % MAXADRS ? "" : "\n"); /* Munge will do all the work to output it */ munge (the_addr); /* Reclaim the space */ ap_sqdelete (the_addr, (AP_ptr) 0); ap_free (the_addr); if (debug) printf ("munged and space freed\n"); break; case DONE: if (debug) printf ("hadr_munge all done\n"); /* Reclaim the space */ ap_sqdelete (the_addr, (AP_ptr) 0); ap_free (the_addr); return; } } } /* We now have a single address in the_addr to output. */ munge (the_addr) AP_ptr the_addr; { char adr[LINESIZE]; char *s, *frees; AP_ptr local, domain, route; if (debug) printf ("in munge with: "); /* Find where the important bits begin in the tree */ ap_t2p (the_addr, (AP_ptr *) 0, (AP_ptr *) 0, &local, &domain, &route); /* Convert from the tree back into a string */ frees = s = ap_p2s_nc ((AP_ptr) 0, (AP_ptr) 0, local, domain, route); if (debug) printf ("%s\n", s); /* Is it a uucp style address? */ if (domain == (AP_ptr) 0 && index (s, '!') != (char *) 0) { char adr2[LINESIZE]; (void) strcpy (adr, s); /* * Stick the path it took to get here at the start. * But try to avoid any duplicates by overlapping * the matching parts of the address. Eg: adr = * 'x!y!z' path = 'a!b!x!y!' adr2 = 'a!b!x!y!z' */ for (s = origpath; *s; s++) { /* Does it match? */ if (strncmp (adr, s, strlen (s)) == 0) { char c = *s; *s = '\0'; (void) strcpy (adr2, origpath); (void) strcat (adr2, adr); *s = c; break; } } /* * Did I just scan the whole path without finding a * match! */ if (*s == '\0') { /* Append the adr to the path */ (void) strcpy (adr2, origpath); (void) strcat (adr2, adr); } /* * Munge the address into its shortest form and * print it */ fromcvt (adr2, adr); fprintf (rm_msgf, "%s", adr); if (debug) printf ("uucp munge gives %s\n", adr); } else { char *p; char *at; char *official = NULL; char *fmt; char *brace; AP_ptr norm; extern int ap_outtype; /* Normalise the address */ ap_outtype = AP_PARSE_733; /* Hmm. Maybe should be * from channel */ norm = ap_normalize (the_addr, CH_USA_PREF); /* Convert it back in to a string and output it */ ap_t2s (norm, &p); if (debug) printf ("Normalised address: %s\n", p); /* * Look for the last address component and re-write * to the */ /* * official form. There are probably better ways of * doing this */ at = rindex (p, '@'); fmt = "%s"; if (at) { brace = index (at + 1, '>'); if (brace) *brace = '\0'; official = strdup (at + 1); if (official) { *at = '\0'; fmt = brace ? "%s@%s>" : "%s@%s"; } else if (brace) *brace = '>'; } fprintf (rm_msgf, fmt, p, official); if (debug) { printf ("arpa munge gives "); printf (fmt, p, official); printf ("\n"); } free (p); } free (frees); } /* * datecvt() -- convert UNIX ctime() style date to ARPA style * (change done in place) */ datecvt (date, newdate) char *date; char *newdate; { /* * LMCL: Changed the default timezone, when none given. */ if (isdigit (date[0]) || date[3] == ',' || isdigit (date[5])) (void) strcpy (newdate, date); /* Probably already ARPA */ else if (isdigit (date[20])) (void) sprintf (newdate, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s GMT", date, date + 8, date + 4, date + 22, date + 11, date + 14, date + 17); else if (isalpha (date[17])) /* LMCL. Bum Unix format */ (void) sprintf (newdate, "%.3s, %.2s %.3s %.2s %.2s:%.2s:00 GMT", date, date + 8, date + 4, date + 23, date + 11, date + 14); else (void) sprintf (newdate, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s %.3s", date, date + 8, date + 4, date + 26, date + 11, date + 14, date + 17, date + 20); } msg_failure (addr, rp, reason) char *addr; RP_Buf *rp; char *reason; { extern char *postmaster; char buf[BUFSIZ]; if (rp) (void) sprintf (buf, "%s: %s [%s]", reason, rp->rp_line, rp_valstr ((int)rp->rp_val)); else (void) sprintf (buf, "%s", reason); PP_LOG (LLOG_EXCEPTIONS, ("Message failure: %s", buf)); return msg_return (postmaster, addr, buf); } msg_return (addr, dest, reason) char *addr, *dest, *reason; { RP_Buf rp; io_end (NOTOK); if (rp_isbad (pps_1adr ("UUCP (rmail) Failed Message", addr, &rp))) bomb ("pps_1adr failed [%s]", rp.rp_line); if (rp_isbad (pps_txt ("Your message was not delivered to:\n ", &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); if (rp_isbad (pps_txt (dest, &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); if (rp_isbad (pps_txt ("\nFor the following reason:\n ", &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); if (rp_isbad (pps_txt (reason, &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); if (rp_isbad (pps_txt ("\n\n--------------- Returned Mail ---------------\n\n", &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); rewind (rm_msgf); if (rp_isbad (pps_file (rm_msgf, &rp))) bomb ("pps_file failed [%s]", rp.rp_line); if (rp_isbad (pps_txt ("--------------- End of Returned Mail -------------\n", &rp))) bomb ("pps_txt failed [%s]", rp.rp_line); if (rp_isbad (pps_end (OK, &rp))) bomb ("pps_end failed [%s]", rp.rp_line); return 0; } /* \f */ static char * pling2norm(to, from) char *to; char *from; { char temp[1024]; char *pling; strcpy(temp, from); *to = '\0'; while (pling = rindex(temp, '!')) { *(pling++) = '\0'; if (*to) strcat(to, "%"); strcat(to, pling); } if (*to) strcat(to, "%"); strcat(to, temp); if (pling = rindex(to, '%')) *pling = '@'; if (debug) printf("%s -> %s\n", from, to); return to; } /* \f */ xsubmit (from, argv, argc) char *from; char **argv; int argc; { char buf[LINESIZE]; RP_Buf rp; struct prm_vars prm; LIST_BPT *new; ADDR *orig = NULL; Q_struct que; char *name = NULL; int i; int first_bp = TRUE; prm_init (&prm); q_init (&que); /* inbound channel, inbound host, contenttype */ prm.prm_opts = PRM_ACCEPTALL; que.msgtype = MT_UMPDU; que.encodedinfo.eit_types = NULLIST_BPT; new = list_bpt_new (hdr_822_bp); list_bpt_add (&que.encodedinfo.eit_types, new); new = list_bpt_new (ia5_bp); list_bpt_add (&que.encodedinfo.eit_types, new); que.inbound = list_rchan_new (origsys, chanptr->ch_name); rewind (rm_msgf); if (debug) { char buff[1024]; for (argv++; --argc > 0; argv++) printf ("arg = %s (%s)\n", pling2norm(buff, *argv), *argv); while (fgets (buf, LINESIZE - 1, rm_msgf) != NULL) printf ("T=%s", buf); if (ferror (rm_msgf)) bomb ("%s", "Error reading messge file"); exit (0); } if (rp_isbad (io_init (&rp))) return msg_failure (from, &rp, "io_init failed"); if (rp_isbad (io_wprm (&prm, &rp))) return msg_failure (from, &rp, "io_wprm failed"); if (rp_isbad (io_wrq (&que, &rp))) return msg_failure (from, &rp, "io_wrq failed"); orig = adr_new (from, AD_822_TYPE, 0); if (rp_isbad (io_wadr (orig, AD_ORIGINATOR, &rp))) return msg_failure (from, &rp, "Sender address unacceptable"); adr_free (orig); for (i = 1; i < argc; i++) { ADDR *adr; char buff[1024]; name = pling2norm(buff, argv[i]); adr = adr_new (name, AD_822_TYPE, i); if (rp_isbad (io_wadr (adr, AD_RECIPIENT, &rp))) return msg_failure (name, &rp, "Recipient address bad"); adr_free (adr); } if (rp_isbad (io_adend (&rp))) return msg_failure (name, &rp, "Address end failed"); if (rp_isbad (io_tinit (&rp))) return msg_failure (name, &rp, "body initialisation failed"); if (rp_isbad (io_tpart (hdr_822_bp, FALSE, &rp))) return msg_failure (name, &rp, "822 header initialisation failed"); rewind (rm_msgf); first_bp = TRUE; while (fgets (buf, LINESIZE - 1, rm_msgf) != NULL) { if (first_bp == TRUE && buf[0] == '\n') { first_bp = FALSE; if (rp_isbad (io_tdend (&rp))) msg_failure (name, &rp, "header end failed"); if (rp_isbad (io_tpart ("1.ia5", FALSE, &rp))) msg_failure (name, &rp, "body initialisation failed"); } if (rp_isbad (io_tdata (buf, strlen (buf)))) msg_failure (name, (RP_Buf *)0, "data copied failed"); } if (ferror (rm_msgf)) msg_failure (name, (RP_Buf *)0, "Data copy failed"); if (rp_isbad (io_tdend (&rp))) msg_failure (name, &rp, "Text termination problem"); if (rp_isbad (io_tend (&rp))) msg_failure (name, &rp, "Termination problem"); (void) io_end (OK); return 0; } /*VARARGS1*/ #ifdef lint bomb (fmt) char *fmt; { return bomb (fmt); } #else bomb (va_alist) va_dcl { va_list ap; char buf[BUFSIZ]; va_start (ap); _asprintf (buf, NULLCP, ap); PP_LOG (LLOG_EXCEPTIONS, ("uucp bombing: %s", buf)); va_end (ap); exit (99); } #endif /* * fromcvt() -- trys to convert the UUCP style path into * an ARPA style name. */ fromcvt (from, newfrom) char *from, *newfrom; { register char *cp; register char *sp; register char *off; char *at; char *atoff; char buf[LINESIZE]; if (debug) printf ("fromcvt on %s\n", from); (void) strcpy (buf, from); cp = rindex (buf, '!'); if (cp == 0) { (void) strcpy (newfrom, from); return; } /* * look for @site at the end of the name */ atoff = NULL; if ((at = index (cp, '@')) != NULL) { /* got one - is it followed by a ! ? */ if (index (at + 1, '!') != NULL) at = NULL; else { /* look up the official name of the at site */ atoff = strdup (at + 1); } } *cp = 0; while (sp = rindex (buf, '!')) { /* * scan the path backwards looking for hosts that * we know about */ if (off = strdup (sp + 1)) { if (atoff && !lexequ (atoff, off)) (void) strcpy (newfrom, cp + 1); else (void) sprintf (newfrom, "%s@%s", cp + 1, off); return; } else if (at && !lexequ (at + 1, sp + 1)) { (void) strcpy (newfrom, cp + 1); return; } *cp = '!'; cp = sp; *cp = 0; } if (off = strdup (buf)) (void) sprintf (newfrom, "%s@%s", cp + 1, off); else (void) sprintf (newfrom, "%s@%s", cp + 1, buf); } /* * This piece added by Peter Collinson (UKC) * rather than just making rmail submit into the uucp channel which * is hard coded. First look up in a table 'rmail.chans' for entries * of the form * nextdoor:channel * If the name exists then use that channel otherwise just default to * the uucp channel. This is for authorisation purposes really */ extern char *uucpin_chan; set_channel (nxt) char *nxt; { if ((chanptr = ch_nm2struct (uucpin_chan)) == NULLCHAN) bomb ("Cannot look up channel '%s'\n", uucpin_chan); } /* * Check if the from machine which we have constructed actually * contains two references to the same machine of the form * site.uucp!site.??.uk!something * if so replace by the single official name */ domain_cross (route) char *route; { char *second; char *endsecond; char *official; char *host_equal (); second = index (route, '!'); if (second == (char *) 0) return; second++; endsecond = index (second, '!'); if (endsecond == (char *) 0) return; second[-1] = '\0'; *endsecond = '\0'; if (official = host_equal (route, second)) { (void) strcpy (route, official); *endsecond = '!'; (void) strcat (route, endsecond); } else { second[-1] = '!'; *endsecond = '!'; } } /* * host_equal * a routine to see whether the strings which are input * are in fact the same host * Returns the official name if they are and a null pointer if not */ char * host_equal (n1, n2) char *n1, *n2; { if (lexequ (n1, n2) == 0) return n1; return NULLCP; }