home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / fax / fax_in.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  12.5 KB  |  568 lines

  1. /* faxd.c: PP skelton for inbound fax deamon */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/fax/RCS/fax_in.c,v 6.0 1991/12/18 20:07:09 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/fax/RCS/fax_in.c,v 6.0 1991/12/18 20:07:09 jpo Rel $
  9.  *
  10.  * $Log: fax_in.c,v $
  11.  * Revision 6.0  1991/12/18  20:07:09  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15. #include    "util.h"
  16. #include    "IOB-types.h"
  17. #include    "prm.h"
  18. #include    "q.h"
  19. #include    "retcode.h"
  20. #include    "sys.file.h"
  21. #include    "ap.h"
  22. #include    "or.h"
  23. #include    <varargs.h>
  24. #include     "faxgeneric.h"
  25.  
  26. void    advise ();
  27. void    adios ();
  28. #define ps_advise(ps, f) \
  29.         advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s",\
  30.                 (f), ps_error ((ps) -> ps_errno))
  31.  
  32. extern FaxCtlr    *init_faxctrlr();
  33. extern struct type_IOB_ORName    *orn2orname();
  34. extern char    *quedfldir;
  35.  
  36. static void dirinit();
  37.  
  38. CHAN    *mychan;
  39. struct    type_IOB_InformationObject    *infoobj = NULL;
  40. struct    prm_vars    params;
  41. Q_struct        Qstruct;
  42. FaxCtlr    *faxctl = NULL;
  43. char msgid [LINESIZE];
  44.  
  45. /* not actually used */
  46. int table_verified = FALSE;
  47.  
  48. main (argc, argv)
  49. int    argc;
  50. char    **argv;
  51. {   
  52.     struct type_IOB_G3FacsimileBodyPart     *g3fax;
  53.     sys_init (argv[0]);
  54.     dirinit();
  55.  
  56.     if ((faxctl = init_faxctrlr(FAX_INBOUND,
  57.                     argc, 
  58.                     argv)) == (FaxCtlr *) NULL) {
  59.         err_abrt(RP_MECH,
  60.              "Unable to initialise fax driver specific elements");
  61.     }
  62.  
  63.     if (init_PP_stuff(faxctl) != OK)
  64.         err_abrt(RP_MECH,
  65.              "Unable to initialise PP specfics");
  66.     fillin_infoobj(&infoobj, faxctl);
  67.  
  68.     /* daemon so continually loop */
  69.     while (1) {
  70.         if (faxctl->receiveG3Fax == NULLIFP) {
  71.             err_abrt(RP_MECH,
  72.                  "No receiveG3Fax procedure given for fax driver");
  73.         }
  74.  
  75.         if ((*faxctl->receiveG3Fax) (faxctl, &g3fax) != OK) {
  76.             PP_LOG (LLOG_EXCEPTIONS,
  77.                 ("fax receiveG3Fax failed ['%s']",
  78.                  faxctl->errBuf));
  79.         } else if (deal_with_fax (faxctl, g3fax) != OK) {
  80.             /* have accepted fax from remote */
  81.             /* ought to dump somewhere */
  82.             /* so as not to lose it */
  83.             PP_LOG(LLOG_EXCEPTIONS,
  84.                    ("failed to deal with incoming fax"));
  85.         }
  86.  
  87.         if (g3fax)
  88.             free_IOB_G3FacsimileBodyPart (g3fax);
  89.     }
  90. }
  91.  
  92. /* --- routine to move to correct place in file system --- */
  93. static void dirinit()
  94. {
  95.     if (chdir (quedfldir) < 0)
  96.         err_abrt (RP_LIO,
  97.               "Unable to change directory to '%s'", quedfldir);
  98. }
  99.  
  100. /*   */
  101.  
  102. /* wrap up fax and submit */
  103. deal_with_fax(faxctl, fax)
  104. FaxCtlr    *faxctl;
  105. struct type_IOB_G3FacsimileBodyPart    *fax;
  106. {
  107.     PE    pe = NULLPE;
  108.     
  109.     if (infoobj -> un.ipm -> heading -> this__IPM != 
  110.         (struct type_IOB_IPMIdentifier *) NULL)
  111.         free_IOB_IPMIdentifier (infoobj -> un.ipm -> heading -> this__IPM);
  112.     gen_mid (&(infoobj -> un.ipm -> heading -> this__IPM));
  113.     infoobj -> un.ipm -> body ->BodyPart->un.g3__facsimile = fax;
  114.     if (encode_IOB_InformationObject (&pe, 1, 0, NULLCP, infoobj) != OK) {
  115.         PP_OPER(NULLCP,
  116.             ("deal_with_fax failed to encode info object [%s]", PY_pepy));
  117. /*        send_to_printer(fax)*/
  118.         return NOTOK;
  119.     }
  120.     
  121.     submitPE (pe);
  122.     
  123.     if (pe != NULLPE) pe_free(pe);
  124.  
  125.     return OK;
  126. }
  127.  
  128. /*   */
  129.  
  130. int    io_running = FALSE;
  131.  
  132. stop_io()
  133. {
  134.     if (io_running == TRUE)
  135.         io_end(NOTOK);
  136.     io_running = FALSE;
  137. }
  138.  
  139. submitPE (pe)
  140. PE    pe;
  141. {
  142.     PS    ps;
  143.         RP_Buf                  rps, *rp = &rps;
  144.     
  145.     if (io_running == FALSE) {
  146.         if (rp_isbad (io_init(rp))) {
  147.             PP_LOG(LLOG_EXCEPTIONS,
  148.                    ("io_init err %s", rp -> rp_line));
  149.             exit (1);
  150.         }
  151.         io_running = TRUE;
  152.     }
  153.  
  154.     if ((ps = ps_alloc(str_open)) == NULLPS) {
  155.         ps_advise (ps, "ps_alloc");
  156.         exit(1);
  157.     }
  158.  
  159.     if (str_setup (ps, NULLPE, 0, 0) == NOTOK) {
  160.         advise (NULLCP, "str_setup loses");
  161.         exit (1);
  162.     }
  163.  
  164.     if (pe2ps(ps, pe) == NOTOK) {
  165.         ps_advise(ps, "pe2ps loses");
  166.         exit(1);
  167.     }
  168.  
  169.     if (rp_isbad (io_wprm (¶ms, rp))) {
  170.         PP_LOG(LLOG_EXCEPTIONS,
  171.                ("io_wprm err %s",
  172.             rp -> rp_line));
  173.         stop_io();
  174.         exit (1);
  175.     }
  176.         if (rp_isbad (io_wrq (&Qstruct, rp))) {
  177.                 PP_LOG (LLOG_EXCEPTIONS, ("io_wrq err %s",
  178.                                           rp -> rp_line));
  179.         stop_io();
  180.         exit(1);
  181.         }
  182.  
  183.         if (rp_isbad (io_wadr (Qstruct.Oaddress, AD_ORIGINATOR, rp))) {
  184.                 PP_OPER (NULLCP, ("io_wadr originator/postmaster err %s",
  185.                                           rp -> rp_line));
  186.         stop_io();
  187.         exit (1);
  188.         }
  189.  
  190.         if (rp_isbad (io_wadr (Qstruct.Raddress, AD_RECIPIENT, rp))) {
  191.                 PP_LOG (LLOG_EXCEPTIONS, ("io_wadr recipient err %s",
  192.                                           rp -> rp_line));
  193.         stop_io();
  194.         exit (1);
  195.     }
  196.  
  197.         if (rp_isbad (io_adend (rp))) {
  198.                 PP_LOG (LLOG_EXCEPTIONS, ("io_adend err %s",
  199.                                           rp -> rp_line));
  200.         stop_io();
  201.         exit (1);
  202.         }
  203.  
  204.     if (rp_isbad (io_tinit (rp))) {
  205.         PP_LOG (LLOG_EXCEPTIONS,
  206.             ("tinit blows %s", rp -> rp_line));
  207.         stop_io();
  208.     }
  209.     if (rp_isbad (io_tpart (Qstruct.cont_type, FALSE, rp))) {
  210.         PP_LOG (LLOG_EXCEPTIONS,
  211.             ("io_tpart blows %s", rp -> rp_line));
  212.         stop_io();
  213.         exit (1);
  214.     }
  215.     if (rp_isbad (io_tdata(ps->ps_base, 
  216.                    ps -> ps_ptr - ps -> ps_base))) {
  217.         PP_LOG(LLOG_EXCEPTIONS, ("io_tdata error"));
  218.         stop_io();
  219.         exit (1);
  220.     }
  221.     
  222.     if (rp_isbad (io_tdend (rp))) {
  223.         PP_LOG (LLOG_EXCEPTIONS, ("io_tdend fails"));
  224.         stop_io();
  225.         exit(1);
  226.     }
  227.     
  228.     if (rp_isbad (io_tend (rp))) {
  229.         PP_LOG (LLOG_EXCEPTIONS, ("io_tend fails"));
  230.         stop_io();
  231.         exit(1);
  232.     }
  233.  
  234.     ps_free(ps);
  235. }
  236.  
  237. /*   */
  238. /* copied from dr2rfc code */
  239.  
  240. /* build up structures need to submit fax into PP */
  241. extern char    *loc_dom_mta, *cont_p22, *hdr_p22_bp, *hdr_p2_bp;
  242. extern char    *getpostmaster();
  243.  
  244. static init_PP_stuff(faxctl)
  245. FaxCtlr    *faxctl;
  246. {
  247.         EncodedIT               *ep = &Qstruct.encodedinfo;
  248.  
  249.     if ((mychan = ch_nm2struct (faxctl->channel)) == NULLCHAN) {
  250.         PP_OPER (NULLCP,
  251.              ("Channel '%s' not known", faxctl->channel));
  252.         exit(1);
  253.     }
  254.  
  255.     if (decode_ch_in_info(mychan -> ch_in_info, faxctl) != OK)
  256.         return NOTOK;
  257.     
  258.     prm_init(¶ms);
  259.     params.prm_opts = PRM_ACCEPTALL | PRM_NOTRACE;
  260.     q_init (&Qstruct);
  261.     Qstruct.msgtype = MT_UMPDU;
  262.     Qstruct.inbound = list_rchan_new (loc_dom_mta,
  263.                       faxctl->channel);
  264.     Qstruct.cont_type = strdup(mychan -> ch_content_in);
  265.  
  266.     /* eits completely run by tailoring */
  267.     ep->eit_types = NULL;
  268.     if (mychan->ch_hdr_in != NULLIST_BPT)
  269.         list_bpt_add(&ep->eit_types, 
  270.                  list_bpt_dup(mychan -> ch_hdr_in));
  271.     else
  272.         list_bpt_add(&ep->eit_types, 
  273.                  list_bpt_new((lexequ(mychan -> ch_content_in, 
  274.                           cont_p22) ==  0) ? 
  275.                       hdr_p22_bp : hdr_p2_bp));
  276.     if (mychan->ch_bpt_in != NULLIST_BPT)
  277.         list_bpt_add(&ep->eit_types, 
  278.                  list_bpt_dup(mychan -> ch_bpt_in));
  279.     else
  280.         list_bpt_add(&ep->eit_types,
  281.                  list_bpt_new("g3fax"));
  282.  
  283.         /* -- create the ADDR struct for orig and recipient -- */
  284.         Qstruct.Oaddress            = adr_new (getpostmaster(mychan->ch_in_ad_type), 
  285.                            mychan->ch_in_ad_type, 0);
  286.         Qstruct.Raddress            = adr_new (faxctl->fax_recip, 
  287.                            mychan->ch_in_ad_type, 1);
  288.     return OK;
  289. }
  290.  
  291. static int decode_ch_in_info (info, faxctl)
  292. char    *info;
  293. FaxCtlr    *faxctl;
  294. {
  295.     char  *info_copy;
  296.     int   margc,i;
  297.     char  *margv[100];
  298.  
  299.     if (info == NULLCP) 
  300.         return OK;
  301.  
  302.     info_copy = strdup(info);
  303.     margc = sstr2arg(info_copy, 100, margv, ",=");
  304.   
  305.     for (i = 0; i < margc; i++) {
  306.         /* PP specific args */
  307.         if (faxctl->arg_parse != NULLIFP) {
  308.             /* pass to driver specific parser */
  309.             if ((*faxctl->arg_parse) (faxctl, 
  310.                           margv[i], 
  311.                           margv[i+1]) == OK)
  312.                 i++;
  313.             else {
  314.                 PP_LOG(LLOG_EXCEPTIONS,
  315.                        ("%s", faxctl->errBuf));
  316.                 free(info_copy);
  317.                 return NOTOK;
  318.             }
  319.         } else {
  320.             PP_LOG(LLOG_EXCEPTIONS,
  321.                    ("No arg_parse routine registered, unrecognised ch_info element '%s'",
  322.                 margv[i]));
  323.             free(info_copy);
  324.             return NOTOK;
  325.         }
  326.     }
  327.     free(info_copy);
  328.     return OK;
  329. }
  330.  
  331.     
  332. /*   */
  333. /* copied from p2flatten code */
  334.  
  335. fillin_infoobj(pinfoobj, faxctl)
  336. struct type_IOB_InformationObject    **pinfoobj;
  337. FaxCtlr    *faxctl;
  338. {
  339.     *pinfoobj = (struct type_IOB_InformationObject *) calloc(1,
  340.                           sizeof(struct type_IOB_InformationObject));
  341.     (*pinfoobj)->offset = type_IOB_InformationObject_ipm;
  342.     fillin_ipm(&((*pinfoobj)->un.ipm), faxctl);
  343. }
  344.  
  345. int    fillin_ipm(pipm, faxctl)
  346. struct type_IOB_IPM    **pipm;
  347. FaxCtlr    *faxctl;
  348. {
  349.     *pipm = (struct type_IOB_IPM *)
  350.         calloc(1, sizeof(struct type_IOB_IPM));
  351.     fillin_heading(&((*pipm)->heading), faxctl);
  352.     fillin_body(&((*pipm)->body), faxctl);
  353. }
  354.  
  355. int    fillin_heading(pheading, faxctl)
  356. struct type_IOB_Heading    **pheading;
  357. FaxCtlr    *faxctl;
  358. {
  359.     /* stright from rfc1148 code */
  360.     struct type_IOB_Heading *head;
  361.  
  362.     head = (struct type_IOB_Heading *)
  363.         calloc (1, sizeof (struct type_IOB_Heading));
  364.  
  365.     fillin_sender (&(head->originator), faxctl);
  366.     fillin_recip_seq(&(head->primary__recipients), faxctl);
  367.     fillin_subject(&(head->subject), faxctl);
  368.         
  369.     *pheading = head;
  370. }
  371.  
  372. int    fillin_sender (poriginator, faxctl)
  373. struct type_IOB_OriginatorField    *poriginator;
  374. FaxCtlr    *faxctl;
  375. {
  376.     fillin_ORdesc(poriginator, faxctl,
  377.               getpostmaster(mychan->ch_in_ad_type),
  378.               mychan->ch_in_ad_type);
  379. }
  380.  
  381. int    fillin_recip_seq(or_recip_ptr, faxctl)
  382. struct type_IOB_RecipientSequence    **or_recip_ptr;
  383. FaxCtlr    *faxctl;
  384. {
  385.     *or_recip_ptr = (struct type_IOB_RecipientSequence *)
  386.         calloc (1, sizeof(struct type_IOB_RecipientSequence));
  387.     fillin_recip(&(*or_recip_ptr)->RecipientSpecifier, faxctl);
  388. }
  389.  
  390. int    fillin_recip(precip, faxctl)
  391. struct type_IOB_RecipientSpecifier    **precip;
  392. FaxCtlr    *faxctl;
  393. {
  394.     *precip = (struct type_IOB_RecipientSpecifier *)
  395.         calloc(1, sizeof(struct type_IOB_RecipientSpecifier));
  396.     fillin_ORdesc(&(*precip)->recipient, faxctl, 
  397.               faxctl->fax_recip, mychan->ch_in_ad_type);
  398. }
  399.  
  400. int    fillin_ORdesc(pdesc, faxctl, addr, type)
  401. struct type_IOB_ORDescriptor    **pdesc;
  402. FaxCtlr    *faxctl;
  403. char    *addr;
  404. int    type;
  405. {
  406.     char    buf[BUFSIZ];
  407.     PE    pe;
  408.     ORName    orn;
  409.     int    retval;
  410.     OR_ptr    or;
  411.     *pdesc = (struct type_IOB_ORDescriptor *)
  412.         calloc (1, sizeof(struct type_IOB_ORDescriptor));
  413.  
  414.     switch (type) {
  415.         case AD_X400_TYPE:
  416.         or = or_std2or(addr);
  417.         break;
  418.         default:
  419.         sprintf(buf, "%s", addr);
  420.         retval = or_rfc2or(buf, &or);
  421.         break;
  422.     }
  423.  
  424.     or = or_default(or);
  425.     orn.on_or = or;
  426.     orn.on_dn = (DN) NULL;
  427.     (*pdesc)->formal__name    = orn2orname(&orn);
  428.     or_free(or);
  429. }        
  430.  
  431. int    fillin_subject(subject_ptr, faxctl)
  432. struct type_IOB_SubjectField    **subject_ptr;
  433. FaxCtlr    *faxctl;
  434. {
  435.     *subject_ptr = (struct type_IOB_SubjectField *) 
  436.         calloc (1, sizeof(struct type_IOB_SubjectField));
  437.     
  438.     *subject_ptr = str2qb (faxctl->subject, 
  439.                    strlen(faxctl->subject), 1);
  440. }
  441.  
  442. int    fillin_body(pbody, faxctl)
  443. struct type_IOB_Body     **pbody;
  444. FaxCtlr    *faxctl;
  445. {
  446.     struct type_IOB_Body    *temp;
  447.  
  448.     temp = (struct type_IOB_Body *) 
  449.         calloc(1, sizeof(struct type_IOB_Body));
  450.     temp -> BodyPart = (struct type_IOB_BodyPart *)
  451.         calloc(1, sizeof(struct type_IOB_BodyPart));
  452.     temp->BodyPart->offset = type_IOB_BodyPart_g3__facsimile;
  453.     *pbody = temp;
  454. }
  455.  
  456. gen_mid (mid_ptr)               /* generate  random mailid */
  457. struct type_IOB_IPMIdentifier **mid_ptr;
  458. {
  459.     OR_ptr    or;
  460.     ORName    orn;
  461.     long    now;
  462.  
  463.     if (*mid_ptr)
  464.         free_IOB_IPMIdentifier(*mid_ptr);
  465.     *mid_ptr = (struct type_IOB_IPMIdentifier *) 
  466.         calloc (1,sizeof (struct type_IOB_IPMIdentifier));
  467.  
  468.     (void) time (&now);
  469.         sprintf (msgid, "%ld %s", getpid(), ctime (&now));
  470.         msgid [strlen(msgid) - 1] = '\0';
  471.     (*mid_ptr)->user__relative__identifier = str2qb(msgid,
  472.                             strlen(msgid),
  473.                             1);
  474.     or = or_std2or(getpostmaster(AD_X400_TYPE));
  475.     or = or_default(or);
  476.     orn.on_or = or;
  477.     orn.on_dn = (DN) NULL;
  478.     (*mid_ptr)->user = orn2orname(orn);
  479.     or_free(or);
  480.  
  481. }
  482.  
  483. /* 
  484.  * various isode-like routines
  485.  */
  486.  
  487. /* pe_done: utility routine to do the right thing for pe errors */
  488. int             pe_done (pe, msg)
  489. PE              pe;
  490. char            *msg;
  491. {
  492.         if (pe->pe_errno)
  493.         {
  494.                 PP_OPER(NULLCP,
  495.                         ("%s: [%s] %s",msg,PY_pepy,pe_error(pe->pe_errno)));
  496.                 pe_free (pe);
  497.                 return NOTOK;
  498.         }
  499.         else
  500.         {
  501.                 pe_free (pe);
  502.                 return OK;
  503.         }
  504. }
  505.  
  506. /* ps_done: like pe_done */
  507. int             ps_done (ps, msg)
  508. PS              ps;
  509. char           *msg;
  510. {
  511.         ps_advise (ps, msg);
  512.         ps_free (ps);
  513.         return NOTOK;
  514. }
  515.  
  516. #ifndef lint
  517. void    adios (va_alist)
  518. va_dcl
  519. {
  520.         va_list ap;
  521.  
  522.         va_start (ap);
  523.  
  524.         _ll_log (pp_log_norm, LLOG_FATAL, ap);
  525.  
  526.         va_end (ap);
  527.  
  528.         _exit (1);
  529. }
  530. #else
  531. /* VARARGS2 */
  532.  
  533. void    adios (what, fmt)
  534. char   *what,
  535.        *fmt;
  536. {
  537.         adios (what, fmt);
  538. }
  539. #endif
  540.  
  541.  
  542. #ifndef lint
  543. void    advise (va_alist)
  544. va_dcl
  545. {
  546.         int     code;
  547.         va_list ap;
  548.  
  549.         va_start (ap);
  550.  
  551.         code = va_arg (ap, int);
  552.  
  553.         _ll_log (pp_log_norm, code, ap);
  554.  
  555.         va_end (ap);
  556. }
  557. #else
  558. /* VARARGS3 */
  559.  
  560. void    advise (code, what, fmt)
  561. char   *what,
  562.        *fmt;
  563. int     code;
  564. {
  565.         advise (code, what, fmt);
  566. }
  567. #endif
  568.