home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / prog / pr_wtmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  6.3 KB  |  306 lines

  1. /*
  2.  *    MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  3.  *
  4.  *    Department of Electrical Engineering
  5.  *    University of Delaware
  6.  *    Newark, Delaware  19711
  7.  *
  8.  *
  9.  *    Program Channel: Take message and feed a request to a program
  10.  *
  11.  *
  12.  *    P R _ W T M A I L . C
  13.  *    =====================
  14.  *
  15.  *    ?
  16.  *
  17.  *    J.B.D.Pardoe
  18.  *    University of Cambridge Computer Laboratory
  19.  *    October 1985
  20.  *    
  21.  *    based on the UUCP channel by Doug Kingston (US Army Ballistics 
  22.  *    Research Lab, Aberdeen, Maryland: <dpk@brl>)
  23.  *
  24.  */
  25.  
  26. #include "util.h"
  27. #include "mmdf.h"
  28. #include "ch.h"
  29. #include "ap.h"
  30.  
  31. extern struct ll_struct *logptr;
  32. extern Chan *chan;
  33. extern int errno;
  34. extern int pipebroken;
  35. extern char *locfullname;
  36.  
  37. extern int ap_outtype;
  38. extern AP_ptr ap_s2tree ();
  39.  
  40. /*
  41.  * local variables
  42.  */
  43.  
  44. static FILE *pipefd;
  45. static char hostadr[ADDRSIZE];
  46.  
  47. pr_wtadr (host, adr, from)
  48.     char *host, *adr, *from;
  49. {
  50.     char        *index (), *rindex ();
  51.     FILE        *popen();
  52.     char        *confstr;
  53.     char        command[LINESIZE];
  54.     char    local[ADDRSIZE];
  55.     AP_ptr      ap, ap_local, ap_domain, ap_route;
  56.     int        ap_outtype_save;
  57.  
  58.  
  59.     ap_outtype = chan->ch_apout;
  60.  
  61. #ifdef DEBUG
  62.     printx (
  63.     "pr_wtadr:\n  host: %s\n  addr: %s\n  from: %s\n  ap: 0%o\n",
  64.         host, adr, from, ap_outtype);
  65. #endif /* DEBUG */
  66.  
  67.  
  68. /*  get the host address from the channel table  */
  69.  
  70.     strcpy (hostadr, "");
  71.     if (isstr (host)) {
  72.     if (tb_k2val (chan->ch_table, TRUE, host, hostadr) != OK)
  73.         return (RP_USER);       /* No such host */
  74.     }
  75.  
  76.  
  77. /*  flip the host name if necessary  */
  78.  
  79.     if (ap_outtype & AP_BIG) { /* is this the correct test? (JBDP) */
  80.     host = ap_dmflip (host);
  81. #ifdef DEBUG
  82.     printx ("  host flipped: %s\n", host);
  83. #endif /* DEBUG */
  84.     }
  85.  
  86.  
  87. /*  reformat the `from' address  */
  88.  
  89.     ap_outtype_save = ap_outtype;
  90.     if ((ap = ap_s2tree (from)) == (AP_ptr) NOTOK) {
  91.     ll_log (logptr, LLOGTMP, "Failure to parse address `%s'", from);
  92.     return (RP_PARM);
  93.     }
  94.     ap_t2parts (ap, (AP_ptr *)0, (AP_ptr *)0, &ap_local, &ap_domain, &ap_route);
  95.     from = ap_p2s ((AP_ptr)0, (AP_ptr)0, ap_local, ap_domain, ap_route);
  96.     ap_outtype = ap_outtype_save;
  97. #ifdef DEBUG
  98.     printx ("  reformatted From: %s\n", from);
  99. #endif /* DEBUG */
  100.  
  101.  
  102. /*  extract the `local' part of the address  */
  103.  
  104.     if ((ap = ap_s2tree (adr)) == (AP_ptr) NOTOK) {
  105.     ll_log (logptr, LLOGTMP, "Failure to parse address `%s'", adr);
  106.     return (RP_PARM);
  107.     }
  108.     ap_t2parts (ap,
  109.     /* group  */ (AP_ptr *) 0,
  110.     /* name   */ (AP_ptr *) 0,
  111.     /* local  */ &ap_local,
  112.     /* domain */ (AP_ptr *) 0,
  113.     /* route  */ (AP_ptr *) 0);
  114.  
  115. /* who are we ? */
  116.  
  117.     if (isstr(chan->ch_lname) && isstr(chan->ch_ldomain))
  118.     sprintf(local, "%s.%s", chan->ch_lname, chan->ch_ldomain);
  119.     else
  120.     strcpy(local, locfullname);
  121.  
  122. /*  set the variables; generate the command and execute  */
  123.  
  124.     set_var ("from", from);
  125.     set_var ("local", (ap_outtype & AP_BIG ? ap_dmflip (local) : local));
  126.     set_var ("to", adr);
  127.     set_var ("to.user", ap_local->ap_obvalue);
  128.     set_var ("to.host", host);
  129.  
  130.     if (!isstr(chan->ch_confstr)) {
  131.     confstr = hostadr;
  132.     } else {
  133.     confstr = chan->ch_confstr;
  134.     set_var ("to.address", hostadr);
  135.     }
  136.     expand_vars (confstr, command);
  137.  
  138.     printx ("queuing mail for %s via %s\n\t[%s]:\n\t%s\n",
  139.         adr, host, hostadr, command);
  140.  
  141.     if ((pipefd = popen (command, "w")) == NULL) {
  142.     ll_log (logptr, LLOGFAT, "popen failed: %d", errno);
  143. #ifdef DEBUG
  144.     printx ("*** popen failed: %d\n", errno);
  145. #endif /* DEBUG */
  146.     return (RP_AGN);
  147.     }
  148.  
  149. #ifdef DEBUG
  150.     ll_log (logptr, LLOGFTR, "Done pr_wtadr().");
  151. #endif
  152.     return (RP_OK);
  153. }
  154.  
  155.  
  156. /*
  157.  * pr_txtcpy ()    --  copy the message body down pipefd
  158.  * ============
  159.  */
  160. pr_txtcpy ()
  161. {
  162.     int  nread;
  163.     char buffer [BUFSIZ];
  164.  
  165. #ifdef DEBUG
  166.     ll_log (logptr, LLOGFTR, "pr_txtcpy ()");
  167. #endif
  168.  
  169.     qu_rtinit (0L);             /* ready to read the text */
  170.  
  171.     nread = sizeof(buffer);
  172.     while (!pipebroken && (rp_gval (qu_rtxt (buffer, &nread)) == RP_OK)) {
  173.     if (fwrite (buffer, sizeof (*buffer), nread, pipefd) == 0) {
  174.         ll_log (logptr, LLOGFAT, "write on pipe error (errno %d)", errno);
  175.         ll_log (logptr, LLOGFAT, "pclose returned %d", pclose (pipefd));
  176.         return (RP_LIO);
  177.     }
  178.     nread = sizeof(buffer);
  179.     }
  180.  
  181.     fflush (pipefd);
  182.     if (pipebroken) {
  183.     ll_log (logptr, LLOGFAT, "pipe broke -- probably bad host");
  184.     pclose (pipefd);
  185.     return (RP_LIO);
  186.     }
  187.  
  188.     return (RP_MOK); /* got the text out */
  189. }
  190.  
  191. /*
  192.  * pr_wttend ()  --  Cleans up after the program
  193.  */
  194. pr_wttend ()
  195. {
  196.     return ((pclose (pipefd) != 0) ? RP_LIO : RP_MOK);
  197. }
  198.  
  199.  
  200. /*
  201.  * variables 
  202.  * =========
  203.  */
  204.  
  205. struct var { char *var_name, *var_value; } variables [] = {
  206.     { "from",        (char *)0 },
  207.     { "local",        (char *)0 },
  208.     { "to",        (char *)0 },
  209.     { "to.user",    (char *)0 },
  210.     { "to.host",    (char *)0 },
  211.     { "to.address",    (char *)0 },
  212.     { (char *)0,    (char *)0 }
  213. };
  214.  
  215.  
  216. set_var (name, value)
  217.     char *name, *value;
  218. {
  219.     register struct var *v;
  220.     
  221.     for (v = &variables[0]; v->var_name != (char *)0; v++) {
  222.     if (strcmp (v->var_name, name) == 0) {
  223.         v->var_value = value;
  224.         return;
  225.     }
  226.     }
  227. #ifdef DEBUG
  228.     printx ("*** invalid variable $(%s)\n", name);
  229. #endif /* DEBUG */
  230.     err_abrt (RP_MECH, "invalid variable $(%s)", name);
  231. }
  232.  
  233.  
  234. expand_vars (p, q)
  235.     register char *p, *q;
  236. {
  237.     register char ch;
  238.  
  239.     while ((ch = *p++) != '\0') {
  240.     if (ch == '$') {
  241.         char name [10];
  242.         register char *s;
  243.         register struct var *v;
  244.  
  245.         if (*p++ != '(') {
  246. #ifdef DEBUG
  247.         printx ("*** missing `('\n");
  248. #endif /* DEBUG */
  249.         err_abrt (RP_MECH, "missing `('");
  250.         }
  251.         s = &name[0];
  252.         while ((ch = *p++) != ')') {
  253.         if (ch == '\0') {
  254. #ifdef DEBUG
  255.             printx ("*** missing `)'\n");
  256. #endif /* DEBUG */
  257.             err_abrt (RP_MECH, "missing `)'");
  258.         }
  259.         *s++ = uptolow (ch);
  260.         }
  261.         *s = '\0';
  262.  
  263.         s = (char *)0;
  264.         for (v = &variables[0]; v->var_name != (char *)0; v++) {
  265.         if (strcmp (v->var_name, name) == 0) {
  266.             s = v->var_value;
  267.             if (s == (char *)0) {
  268. #ifdef DEBUG
  269.             printx ("*** variable $(%s) unset\n", name);
  270. #endif
  271.             err_abrt (RP_MECH, "variable $(%s) unset", name);
  272.             }
  273.             while (*q++ = *s++) ;
  274.             --q;
  275.             break;
  276.         }
  277.         }
  278.         if (s == (char *)0) {
  279. #ifdef DEBUG
  280.         printx ("*** invalid variable $(%s)\n", name);
  281. #endif /* DEBUG */
  282.         err_abrt (RP_MECH, "invalid variable $(%s)", name);
  283.         }
  284.  
  285.     } else {
  286.  
  287.         *q++ = ch;
  288.  
  289.     }
  290.     }
  291.     *q = '\0';
  292. }
  293.  
  294.  
  295.  
  296.  
  297. /*
  298.  * lowerfy ()  -  convert string to lower case
  299.  */
  300. lowerfy (strp)
  301.     char *strp;
  302. {
  303.     while (*strp = uptolow (*strp)) strp++;
  304. }
  305.  
  306.