home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Format / rfc1148 / c-RFCtoP2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  13.5 KB  |  618 lines

  1. /* c-P2toRfc.c: rfc987(P2toRFC) filter channel */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Format/rfc1148/RCS/c-RFCtoP2.c,v 6.0 1991/12/18 20:20:34 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Format/rfc1148/RCS/c-RFCtoP2.c,v 6.0 1991/12/18 20:20:34 jpo Rel $
  9.  *
  10.  * $Log: c-RFCtoP2.c,v $
  11.  * Revision 6.0  1991/12/18  20:20:34  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "head.h"
  20. #include "qmgr.h"
  21. #include "q.h"
  22. #include "prm.h"
  23. #include "chan.h"
  24. #include <isode/cmd_srch.h>
  25. #include <sys/stat.h>
  26. #include "sys.file.h"
  27. #include <isode/usr.dirent.h>
  28.  
  29.  
  30. extern char    *quedfldir;
  31. extern char     *chndfldir;
  32. extern char    *cont_p2, *hdr_822_bp, *hdr_p2_bp, *hdr_p22_bp;
  33. extern void    rd_end(), sys_init(), or_myinit(), err_abrt();
  34.  
  35. CHAN         *mychan;
  36. char        *this_msg, *this_chan;
  37. int        err_fatal;
  38.  
  39. static struct type_Qmgr_DeliveryStatus *process ();
  40. static int initialise ();
  41. static int security_check ();
  42. static int filterMsg();
  43. static int link_rest();
  44. static int x40084;
  45. static int doFilter();
  46. static void dirinit ();
  47. static ADDR *getnthrecip ();
  48.  
  49. /*   */
  50. /* main routine */
  51.  
  52. main (argc, argv)
  53. int     argc;
  54. char    **argv;
  55. {
  56.     sys_init(argv[0]);
  57.     or_myinit();
  58.     dirinit ();
  59. #ifdef PP_DEBUG
  60.     if (argc>1 && (strcmp(argv[1],"debug") == 0))
  61.         debug_channel_control(argc,argv,initialise,process,NULLIFP);
  62.     else
  63. #endif
  64.         channel_control (argc, argv, initialise, process,NULLIFP);
  65. }
  66.  
  67. /*   */
  68. /* routine to move to correct place in file system */
  69.  
  70. static void dirinit ()
  71. {
  72.     if (chdir (quedfldir) < 0)
  73.         err_abrt (RP_LIO, " Unable to change directory to '%s'",
  74.               quedfldir);
  75. }
  76.  
  77. /*   */
  78. /* channel initialise routine */
  79.  
  80. extern int real987;
  81.  
  82. static void do_ch_info_flags(info)
  83. char    *info;
  84. {
  85.     char    *info_copy, *margv[20];
  86.     int    margc, ix;
  87.  
  88.     if (info == NULLCP) return;
  89.  
  90.     info_copy = strdup(info);
  91.     if ((margc = sstr2arg(info_copy, 20, margv, " \t")) > 0) {
  92.         for (ix = 0; ix < margc; ix++) {
  93.             if (lexequ(margv[ix], "rfc987") == 0)
  94.                 real987 = OK;
  95.             else
  96.                 PP_LOG(LLOG_EXCEPTIONS,
  97.                        ("Unknown ch_out_info flag '%s'",
  98.                     margv[ix]));
  99.         }
  100.     }
  101.     free(info_copy);
  102. }
  103.  
  104. static int initialise (arg)
  105. struct type_Qmgr_Channel *arg;
  106. {
  107.     char *name;
  108.  
  109.     name = qb2str(arg);
  110.  
  111.     if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
  112.         PP_OPER(NULLCP,
  113.             ("Chans/rfc987 : Channel '%s' not known",name));
  114.         if (name != NULL) free(name);
  115.         return NOTOK;
  116.     }
  117.  
  118.     if (mychan->ch_out_info) 
  119.         do_ch_info_flags(mychan->ch_out_info);
  120.  
  121.     /* check if a rfc987 channel */
  122.     if (name != NULL) free(name);
  123.  
  124.     ap_use_percent();
  125.     ap_norm_all_domains();
  126.  
  127.     return OK;
  128. }
  129.  
  130. /*   */
  131. /* routine to check if allowed to rfc987 filter this message */
  132. static int security_check (msg)
  133. struct type_Qmgr_ProcMsg *msg;
  134. {
  135.     char *msg_file = NULL, *msg_chan = NULL;
  136.     int result;
  137.  
  138.     result = TRUE;
  139.     msg_file = qb2str (msg->qid);
  140.     msg_chan = qb2str (msg->channel);
  141.  
  142.     if ((mychan == NULLCHAN) || (strcmp(msg_chan,mychan->ch_name) !=0)) {
  143.         PP_LOG(LLOG_EXCEPTIONS,
  144.                ("Chans/rfc987 channel err: '%s'",msg_chan));
  145.         result = FALSE;
  146.     }
  147.     if (msg_file != NULL) free(msg_file);
  148.     if (msg_chan != NULL) free(msg_chan);
  149.     return result;
  150. }
  151.  
  152. /*   */
  153. /* routine called to do rfc987 filter */
  154.  
  155. static struct type_Qmgr_DeliveryStatus *process (arg)
  156. struct type_Qmgr_ProcMsg *arg;
  157. {
  158.     struct prm_vars    prm;
  159.     Q_struct    que;
  160.     ADDR        *sender = NULL;
  161.     ADDR        *recips = NULL;
  162.     int         rcount;
  163.     struct type_Qmgr_UserList     *ix;
  164.     ADDR                *adr;
  165.     char        *error = NULLCP;
  166.  
  167.     bzero((char *) &que,sizeof(que));
  168.     
  169.     delivery_init(arg->users);
  170.     delivery_setall(int_Qmgr_status_messageFailure);
  171.     
  172.     if (security_check(arg) != TRUE)
  173.         return deliverystate;
  174.  
  175.     if (this_msg != NULL) free(this_msg);
  176.     if (this_chan != NULL) free(this_chan);
  177.  
  178.     this_msg = qb2str(arg->qid);
  179.     this_chan = qb2str(arg->channel);
  180.  
  181.     PP_LOG(LLOG_NOTICE,
  182.            ("Chans/rfc987 filtering msg '%s' through '%s'",this_msg, this_chan));
  183.  
  184.     if (rp_isbad(rd_msg(this_msg,&prm,&que,&sender,&recips,&rcount))) {
  185.         PP_LOG(LLOG_EXCEPTIONS,
  186.             ("Format/RFCtoP2 rd_msg err: '%s'",this_msg));
  187.         rd_end();
  188.         return delivery_setallstate (int_Qmgr_status_messageFailure,
  189.                          "Can't read message");
  190.     }
  191.  
  192.     /* check each recipient for processing */
  193.     for (ix = arg->users; ix; ix = ix->next) {
  194.         if ((adr = getnthrecip(&que,ix->RecipientId->parm)) == NULL) {
  195.             PP_LOG(LLOG_EXCEPTIONS,
  196.                 ("Format/RFCtoP2 : failed to find recipient %d of msg '%s'",ix->RecipientId->parm, this_msg));
  197.  
  198.              delivery_setstate(ix->RecipientId->parm,
  199.                       int_Qmgr_status_messageFailure,
  200.                       "Unable to find specified recipient");
  201.             continue;
  202.         }
  203.     
  204.         switch (chan_acheck(adr, mychan, 1, (char **) NULL)) {
  205.             case OK:
  206.             if (filterMsg(this_msg,adr,&que, &error) == NOTOK) {
  207.                 PP_LOG(LLOG_EXCEPTIONS,
  208.                        ("Format/RFCtoP2 : failed to filter msg '%s' for recip '%d' on channel '%s'",this_msg, adr->ad_no, this_chan));
  209.                 delivery_setstate(adr->ad_no,
  210.                           int_Qmgr_status_messageFailure,
  211.                           (error == NULLCP) ? "Failed to do 1138 conversion (RFC -> P2)" : error);
  212.             } else {
  213.                 /* CHANGE update adr->ad_rcnt in struct and in file */
  214.                 adr->ad_rcnt++;
  215.                 wr_ad_rcntno(adr,adr->ad_rcnt);
  216.                 delivery_set(adr->ad_no,int_Qmgr_status_success);
  217.             }
  218.             default:
  219.             break;
  220.         }
  221.         if (error != NULLCP) {
  222.             free(error);
  223.             error = NULLCP;
  224.         }
  225.     }
  226.     rd_end();
  227.     q_free (&que);
  228.     prm_free(&prm);
  229.     return deliverystate;
  230. }
  231.  
  232. /*   */
  233. static int filterMsg (msg,recip,qp,ep)
  234. /* return OK if managed to filter msg through mychan for recip */
  235. char        *msg;
  236. ADDR        *recip;
  237. Q_struct    *qp;
  238. char        **ep;
  239. {
  240.     char    *origdir = NULL,
  241.             *newdir = NULL;
  242.     int    result = OK;
  243.     struct stat statbuf;
  244.  
  245.     if (qid2dir(msg, recip, TRUE, &origdir) != OK) {
  246.         PP_LOG(LLOG_EXCEPTIONS,
  247.                ("Format/RFCtoP2 original directory not found for recipient %d of message '%s'",recip->ad_no, msg));
  248.         *ep = strdup("source directory not found");
  249.         result = NOTOK;
  250.     }
  251.  
  252.     /* temporary change to get new directory name */
  253.     recip->ad_rcnt++;
  254.     if ((result == OK) 
  255.         && (qid2dir(msg, recip, FALSE, &newdir) != OK)) {
  256.         PP_LOG(LLOG_EXCEPTIONS,
  257.                ("Format/RFCtoP2 couldn't construct new directory for recipient '%d' of message '%s'",recip->ad_no, msg));
  258.         *ep = strdup("Unable to construct destination directory");
  259.         result = NOTOK;
  260.     }
  261.     recip->ad_rcnt--;
  262.     
  263.     if ((result == OK)
  264.         && (stat(newdir, &statbuf) == OK)
  265.         && ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
  266.         /* directory already exists and so filter already done */
  267.  
  268.         if (origdir != NULL) free(origdir);
  269.         if (newdir != NULL) free(newdir);
  270.         return OK;
  271.     }
  272.  
  273.     {
  274.         /* content not set go on hdr we're creating */
  275.         LIST_BPT    *ix = mychan -> ch_hdr_out;
  276.         x40084 = FALSE;
  277.         while (ix != NULLIST_BPT) {
  278.             if (lexequ(ix -> li_name, hdr_p2_bp) == 0) {
  279.                 x40084 = TRUE;
  280.                 ix = NULLIST_BPT;
  281.             } else
  282.                 ix = ix->li_next;
  283.         }
  284.     }
  285.     if (result == OK && doFilter(origdir,
  286.                      newdir,
  287.                      msg, 
  288.                      qp,
  289.                      ep,
  290.                      x40084) != OK)
  291.         result = NOTOK;
  292.  
  293.     if (origdir != NULL) free(origdir);
  294.     if (newdir != NULL) free(newdir);
  295.     return result;
  296. }
  297.  
  298. /*   */
  299. char    olddir[MAXPATHLENGTH],
  300.     newdir[MAXPATHLENGTH];
  301.  
  302. int    *dir_flags = NULL,
  303.     num_dir_flags = 0,
  304.     dirlevel = 0;
  305.  
  306. #define    INC    5
  307.  
  308. static void resize_dir_flags()
  309. {
  310.     num_dir_flags += INC;
  311.     if (dir_flags == NULL)
  312.         dir_flags = (int *) calloc((unsigned int) num_dir_flags, sizeof(int));
  313.     else
  314.         dir_flags = (int *) realloc( (char *) dir_flags, 
  315.                         (unsigned) (num_dir_flags * sizeof(int)));
  316. }
  317.  
  318. static int    is_822_hdr(entry)
  319. struct dirent    *entry;
  320. {
  321.     if (strncmp(entry->d_name,hdr_822_bp, strlen(hdr_822_bp)) == 0)
  322.         return 1;
  323.     else        
  324.         return 0;
  325. }
  326.  
  327. static int    get_822_hdr(dir,hdr)
  328. char    *dir;
  329. char    *hdr;
  330. {
  331.     int    num;
  332.     struct dirent    **namelist;
  333.  
  334.     num = _scandir(dir, &namelist, is_822_hdr, NULL);
  335.     if (num != 1) {
  336.         PP_LOG(LLOG_EXCEPTIONS,
  337.                ("Format/RFCtoP2 : cannot find unique 822 hdr file"));
  338.         return NOTOK;
  339.     } 
  340.     sprintf(hdr,"%s/%s",dir,(*namelist)[0].d_name);
  341.     free((char *) namelist);
  342.     return OK;
  343. }
  344.         
  345. static doFilter (orig, new, msg, qp, ep, x40084)
  346. /* filters orig directory through mychan to new directory */
  347. char        *orig,
  348.         *new,
  349.         *msg;
  350. Q_struct    *qp;
  351. char        **ep;
  352. int        x40084;
  353. {
  354.     char        hdrp2[MAXPATHLENGTH],
  355.             hdr822[MAXPATHLENGTH],
  356.             hdr_xtra[MAXPATHLENGTH];
  357.     int        result = OK;
  358.     struct stat     statbuf;
  359.     char        buf[BUFSIZ];
  360.  
  361.     (void) sprintf(newdir, "%s/tmp.%s", 
  362.                msg, mychan->ch_name);
  363.     
  364.     if (stat(newdir, &statbuf) == OK) {
  365.         char    *cmd_line;
  366.         /* exists so remove it */
  367.         cmd_line = malloc((unsigned) (strlen("rm -rf ") +
  368.                            strlen(newdir) + 1));
  369.         sprintf(cmd_line, "rm -rf %s", newdir);
  370.         system(cmd_line);
  371.         if (cmd_line != NULL) free(cmd_line);
  372.     }
  373.  
  374.     if (mkdir(newdir, 0777) != OK) {
  375.         PP_SLOG(LLOG_EXCEPTIONS, newdir,
  376.             ("Can't make directory"));
  377.         (void) sprintf(buf,
  378.                    "Failed to make temp directory '%s'",
  379.                    newdir);
  380.         *ep = strdup(buf);
  381.         result = NOTOK;
  382.     }
  383.  
  384.     if (result == OK) {
  385.         /* filter from orig to newdir */
  386.         sprintf(hdrp2,"%s/%s",newdir,
  387.             (x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
  388.         if (get_822_hdr(orig,hdr822) != OK) 
  389.             return NOTOK;
  390.  
  391.         if (stat(hdr822, &statbuf) != OK) {
  392.             PP_OPER(NULLCP,
  393.                    ("Format/RFCtoP2 : cannot find 822 hdr '%s'",hdr822));
  394.             (void) sprintf (buf,
  395.                     "Cannot find 822 hdr '%s'",
  396.                     hdr822);
  397.             *ep = strdup(buf);
  398.             return NOTOK;
  399.         }
  400.         sprintf(hdr_xtra,"%s/1.ia5",newdir);
  401.         sprintf(olddir,"%s",orig);
  402.  
  403.         result = RFCtoP2(hdr822,hdrp2,hdr_xtra, ep, x40084);
  404.         resize_dir_flags();
  405.         dirlevel = 0;
  406.  
  407.         if (stat(hdr_xtra, &statbuf) == OK)
  408.             /* something in header xtra */
  409.             dir_flags[dirlevel] = TRUE;
  410.         else
  411.             dir_flags[dirlevel] = FALSE;
  412.  
  413.         err_fatal = FALSE;
  414.  
  415.         link_rest(orig, ep);
  416.  
  417.         if (err_fatal == TRUE)
  418.             result = NOTOK;
  419.         /* if success rename newdir to new */
  420.  
  421.         if ((result == OK) && (rename(newdir,new) == -1)) {
  422.             PP_SLOG(LLOG_EXCEPTIONS, "rename",
  423.                 ("Can't rename directory '%s' to '%s'",
  424.                  newdir, new));
  425.             (void) sprintf (buf,
  426.                     "Unable to rename temp dir from '%s' to '%s'",
  427.                     newdir, new);
  428.             *ep = strdup(buf);
  429.             result = NOTOK;
  430.         }
  431.     }
  432.     return result;
  433. }
  434.  
  435. /*   */
  436. /* link rest across from orig to newdir */
  437. /* may have to do some renumbering if 1.ia5 is extra headers */
  438.  
  439. /* origdir and newdir are set to current dirlevel of directories */
  440. char    *linkerror = NULLCP;
  441.  
  442. static int    do_link(entry, x40084)
  443. struct dirent    *entry;
  444. int    x40084;
  445. {
  446.     struct    stat statbuf;
  447.     struct dirent    **namelist;
  448.     int        num;
  449.     char        oldfullname[MAXPATHLENGTH],
  450.             newfullname[MAXPATHLENGTH],
  451.             *ix;
  452.  
  453.     if ((strcmp(entry->d_name,".") == 0)
  454.         || (strcmp(entry->d_name,"..") == 0))
  455.         return 0;
  456.  
  457.     if (strncmp(entry->d_name,"hdr.822",7) == 0)
  458.         /* already dealt with */
  459.         return 0;
  460.  
  461.     (void) sprintf(oldfullname, "%s/%s",olddir,entry->d_name);
  462.  
  463.     /* create new filename */
  464.  
  465.     if (isdigit(*(entry->d_name))
  466.         && (dir_flags[dirlevel] == TRUE)) {
  467.         /* need to alter number (increment) */
  468.         ix = index(entry->d_name,'.');
  469.         *ix = '\0';
  470.         num = atoi(entry->d_name);
  471.         *ix = '.';
  472.         sprintf(newfullname,"%s/%d%s",newdir,++num,ix);
  473.     } else
  474.         /* just copy */
  475.         sprintf(newfullname,"%s/%s",newdir,entry->d_name);
  476.     
  477.             
  478.     if ((stat(oldfullname,&statbuf) == OK)
  479.         && ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
  480.         /* directory so do scandir on it */
  481.         char        hdrp2[MAXPATHLENGTH],
  482.                 hdr822[MAXPATHLENGTH],
  483.                 hdr_xtra[MAXPATHLENGTH];
  484.         struct stat     statbuf;
  485.  
  486.         if (mkdir(newfullname, 0777) != OK) {
  487.             PP_SLOG(LLOG_EXCEPTIONS, newfullname,
  488.                 ("Can't make directory"));
  489.             exit(-1);
  490.         }
  491.         dirlevel++;
  492.         if (dirlevel >= num_dir_flags)
  493.             resize_dir_flags();
  494.  
  495.         sprintf(olddir, "%s", oldfullname);
  496.         sprintf(newdir, "%s", newfullname);
  497.  
  498.         /* deal with hdr.822 in this directory if there */
  499.         if ((get_822_hdr(olddir,hdr822) == OK)
  500.             && (stat(hdr822, &statbuf) == OK)) {
  501.             sprintf(hdrp2,"%s/%s",
  502.                 newdir,
  503.                 (x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
  504.             sprintf(hdr_xtra,"%s/1.ia5",newdir);
  505.  
  506.             if (RFCtoP2(hdr822,hdrp2,
  507.                     hdr_xtra,&linkerror,x40084) != OK) {
  508.                 err_fatal = TRUE;
  509.                 return 0;
  510.             }
  511.  
  512.             if (stat(hdr_xtra, &statbuf) == OK)
  513.                 /* something in header xtra */
  514.                 dir_flags[dirlevel] = TRUE;
  515.             else
  516.                 dir_flags[dirlevel] = FALSE;
  517.  
  518.         } else 
  519.             PP_LOG(LLOG_EXCEPTIONS,
  520.                    ("Format/RFCtoP2 : cannot find 822 hdr '%s'",hdr822));
  521.             
  522.         num = _scandir(olddir,&namelist, do_link, NULL);
  523.         /* rewind newdir and olddir */
  524.         ix = rindex(olddir,'/');
  525.         *ix = '\0';
  526.         ix = rindex(newdir,'/');
  527.         *ix = '\0';
  528.         dirlevel--;
  529.  
  530.     } else
  531.         /* just link */
  532.         if (link(oldfullname, newfullname) == -1) {
  533.             PP_SLOG(LLOG_EXCEPTIONS, "link",
  534.                    ("Can't link from '%s' to '%s'",oldfullname,newfullname));
  535.             exit(-1);
  536.         }
  537.     return 0;
  538. }
  539.     
  540. static int link_rest(orig, ep)
  541. char    *orig;
  542. char    **ep;
  543. {
  544.     int num;
  545.     struct dirent    **namelist;
  546.  
  547.     dirlevel = 0;
  548.     num = _scandir(orig,&namelist, do_link, NULL);
  549.     if (linkerror != NULLCP) {
  550.         if (*ep == NULLCP) 
  551.             *ep = linkerror;
  552.         else
  553.             free(linkerror);
  554.         linkerror = NULLCP;
  555.     }
  556. }
  557.  
  558. /*   */
  559. /* auxilary routines to extract from lists */
  560. static ADDR *getnthrecip(que, num)
  561. Q_struct    *que;
  562. int        num;
  563. {
  564.     ADDR *ix = que->Raddress;
  565.  
  566.     if (num == 0)
  567.         return que->Oaddress;
  568.     while ((ix != NULL) && (ix->ad_no != num))
  569.         ix = ix->ad_next;
  570.     return ix;
  571. }
  572.  
  573. void    advise (what, fmt, a, b, c, d, e, f, g, h, i, j)
  574. char   *what,
  575.        *fmt,
  576.        *a,
  577.        *b,
  578.        *c,
  579.        *d,
  580.        *e,
  581.        *f,
  582.        *g,
  583.        *h,
  584.        *i,
  585.        *j;
  586. {
  587.     (void) fflush (stdout);
  588.  
  589.     fprintf (stderr, "RFCtoP2 test");
  590.     fprintf (stderr, fmt, a, b, c, d, e, f, g, h, i, j);
  591.     if (what)
  592.     (void) fputc (' ', stderr), perror (what);
  593.     else
  594.     (void) fputc ('\n', stderr);
  595.  
  596.     (void) fflush (stderr);
  597. }
  598.  
  599.  
  600. /* VARARGS 2 */
  601. void    adios (what, fmt, a, b, c, d, e, f, g, h, i, j)
  602. char   *what,
  603.        *fmt,
  604.        *a,
  605.        *b,
  606.        *c,
  607.        *d,
  608.        *e,
  609.        *f,
  610.        *g,
  611.        *h,
  612.        *i,
  613.        *j;
  614. {
  615.     advise (what, fmt, a, b, c, d, e, f, g, h, i, j);
  616.     _exit (1);
  617. }
  618.