|
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 l
Length: 8860 (0x229c) Types: TextFile Names: »local.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/slocal/local.c«
/* local: local delivery channel */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/slocal/RCS/local.c,v 5.0 90/09/20 15:54:01 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/slocal/RCS/local.c,v 5.0 90/09/20 15:54:01 pp Exp Locker: pp $ * * $Log: local.c,v $ * Revision 5.0 90/09/20 15:54:01 pp * rcsforce : 5.0 public release * */ /*********************************************************************\ * * * local channel - deliver to people * * * \*********************************************************************/ #include "head.h" #include "util.h" #include "prm.h" #include "q.h" #include "dr.h" #include "qmgr.h" #include <isode/logger.h> #include <sys/stat.h> #include <pwd.h> #include <sys/file.h> #define TESTVERSION extern char *mquedir; extern char *quedfldir; extern CHAN *ch_nm2struct (); extern char *mboxname; extern char *delim1; extern char *delim2; static CHAN *mychan; static char *this_msg; static struct passwd *pwd; static int initproc (); static int douser (); static int deliver (); static void dirinit (); static struct type_Qmgr_DeliveryStatus *process (); static Q_struct Qstruct; static int copy (); /* --------------------- Begin Routines --------------------------------- */ main (argc, argv) int argc; char **argv; { char *p; p = argv[0]; if (*p == '/') { p = rindex (p, '/'); p++; } /* -- Init the channel - and find out who we are -- */ chan_init (p); dirinit (); #ifdef PP_DEBUG if (argc > 1 && strcmp (argv[1], "debug") == 0) debug_channel_control (argc, argv, initproc, process, NULLIFP); else #endif channel_control (argc, argv, initproc, process, NULLIFP); exit (0); } static int initproc (arg) struct type_Qmgr_Channel *arg; { char *p; p = qb2str (arg); PP_TRACE (("initproc (%s)", p)); if ((mychan = ch_nm2struct (p)) == NULLCHAN) err_abrt (RP_PARM, "Channel '%s' not known", p); PP_NOTICE (("Starting %s (%s)", mychan -> ch_name, mychan -> ch_show)); if (p) free (p); return OK; } static struct type_Qmgr_DeliveryStatus *process (arg) struct type_Qmgr_ProcMsg *arg; { struct type_Qmgr_UserList *up; struct prm_vars prm; Q_struct *qp = &Qstruct; ADDR *ad_sendr = NULL, *ad_recip = NULL; char msgq[FILNSIZE]; int ad_count, retval; bzero ((char *)&prm, sizeof prm); bzero ((char *)qp, sizeof *qp); if (this_msg) free (this_msg); this_msg = qb2str (arg -> qid); PP_NOTICE (("Processing msg %s", this_msg)); (void) sprintf (msgq, "%s%s", mquedir, this_msg); delivery_init (arg -> users); retval = rd_msg (this_msg, &prm, qp, &ad_sendr, &ad_recip, &ad_count); if (rp_isbad (retval)) { PP_LOG (LLOG_EXCEPTIONS, ("local/rd_msg err: %s", this_msg)); return delivery_setall (int_Qmgr_status_messageFailure); } for (up = arg -> users; up; up = up -> next) { retval = douser (up -> RecipientId -> parm, ad_recip, msgq); if (rp_isbad (retval)) break; } rd_end(); prm_free (&prm); q_free (qp); return deliverystate; } /* Change into pp queue space */ static void dirinit () { PP_TRACE (("dirinit ()")); if (chdir (quedfldir) < 0) err_abrt (RP_LIO, "Uanble to change directory to '%s'", quedfldir); } /* * process one extension-id for this message */ static int douser (rno, ad_recip, msgd) int rno; ADDR *ad_recip; char *msgd; { ADDR *ap; PP_TRACE (("douser (%d, ad_recip, %s)", rno, msgd)); for (ap = ad_recip; ap ; ap = ap->ad_next) { if (ap-> ad_status == AD_STAT_DONE) continue; if ( rno == ap -> ad_no) return (deliver (ap, msgd)); } PP_LOG (LLOG_EXCEPTIONS, ("local/user not recipient of %s", this_msg)); delivery_set (rno, int_Qmgr_status_messageFailure); return RP_MECH; } static char *formatdir = NULLCP; /* Do the delivery */ static int deliver (ap, msgd) ADDR *ap; char *msgd; { char *username = NULLCP, *diry = NULLCP, *mbox = NULLCP, mailbox[FILNSIZE], filename[FILNSIZE]; int first = 0, retval; RP_Buf rps, *rp = &rps; PP_TRACE (("local/deliver msgd=%s", msgd)); if (ap->ad_outchan->li_chan != mychan) { PP_LOG (LLOG_EXCEPTIONS, ("local/this extension-id (%d) is not for this chan", ap->ad_extension)); delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure); return RP_BAD; } if (tb_getlocal (ap -> ad_r822adr, mychan, &username, &diry, &mbox) != OK) { PP_LOG (LLOG_EXCEPTIONS, ("User %s not registered in chan %s table", ap -> ad_r822adr, mychan -> ch_name)); delivery_set (ap -> ad_no, int_Qmgr_status_permanentFailure); set_1dr (&Qstruct, ap -> ad_no, DRR_UNABLE_TO_TRANSFER, DRD_UA_UNAVAILABLE, "User not registered in delivery table"); wr_q2dr (&Qstruct, this_msg); return RP_USER; } PP_TRACE (("Found entry for '%s' uid '%s' directory '%s'", ap -> ad_r822adr, username, diry)); if (pwd && strcmp (pwd -> pw_name, username) == 0) PP_TRACE (("Same user")); else { if (pwd) (void) loc_end (); if ((pwd = getpwnam (username)) == NULL) { PP_LOG (LLOG_EXCEPTIONS, ("local/user '%s' not in passwd file", username)); delivery_set (ap -> ad_no, int_Qmgr_status_permanentFailure); set_1dr (&Qstruct, ap -> ad_no, DRR_UNABLE_TO_TRANSFER, DRD_UA_UNAVAILABLE, "user not registered in passwd file"); wr_q2dr (&Qstruct, this_msg); return RP_USER; } if (rp_isbad (loc_init (pwd, diry ? diry : pwd->pw_dir))) { PP_LOG (LLOG_EXCEPTIONS, ("loc_init error")); delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure); return RP_MECH; } } /* Find the correctly formatted version of the message */ if (qid2dir (this_msg, ap, TRUE, &formatdir) == NOTOK) { PP_LOG (LLOG_EXCEPTIONS, ("Can't locate message %s", this_msg)); delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure); return RP_MECH; } PP_DBG (("local: mboxname : '%s'", mboxname)); PP_DBG (("local: delim1 : '%s'", delim1)); PP_DBG (("local: delim2 : '%s'", delim2)); (void) sprintf (mailbox, "%s/%s", diry ? diry : pwd->pw_dir, mbox ? mbox : mboxname); PP_TRACE (("delivering to mailbox='%s'", mailbox)); if (loc_open (mailbox, "a", 1, rp) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("Can't open mailbox %s", rp -> rp_line)); delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure); return RP_MECH; } if (rp_isbad (retval = msg_rinit (formatdir))) { PP_LOG (LLOG_EXCEPTIONS, ("local/msg_rinit can't init %s", formatdir)); (void) loc_close (rp); delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure); return RP_MECH; } PP_TRACE (("Mailbox opened")); if (loc_write (delim1, strlen (delim1), rp) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("loc_write can't write delim1 [%s]", rp -> rp_line)); delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure); return rp -> rp_val; } first = 0; while ((retval = msg_rfile (filename)) == RP_OK) { if (rp_isbad (retval = copy (filename))) break; if (first++ == 0) loc_write ("\n", 1, rp); } if (loc_write (delim2, strlen (delim2), rp) != RP_OK) PP_LOG (LLOG_EXCEPTIONS, ("loc_write can't write delim2 [%s]", rp -> rp_line)); loc_close (rp); retval = msg_rend (); if (retval != RP_OK) { delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure); return retval; } PP_NOTICE ((">>> local : Message delivered to %s", username)); if (ap -> ad_usrreq == AD_USR_CONFIRM || ap -> ad_mtarreq == AD_MTA_CONFIRM || ap -> ad_mtarreq == AD_MTA_AUDIT_CONFIRM) { set_1dr (&Qstruct, ap -> ad_no, DRR_NO_REASON, -1, NULLCP); wr_q2dr (&Qstruct, this_msg); delivery_set (ap -> ad_no, int_Qmgr_status_permanentFailure); } else { (void) wr_ad_status (ap, AD_STAT_DONE); delivery_set (ap -> ad_no, int_Qmgr_status_success); } return RP_OK; } static int copy (fname) char *fname; { FILE *ifp; char buf[BUFSIZ]; int n, retval = RP_OK; RP_Buf rps, *rp = &rps; PP_TRACE (("copy (%s, fp)", fname)); if ((ifp = fopen (fname,"r")) == NULL) { PP_LOG (LLOG_EXCEPTIONS, ("local/can't read file '%s'", fname)); return (RP_FOPN); } while ((n = fread (buf, sizeof (char), sizeof (buf), ifp)) > 0) if (loc_write (buf, n, rp) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("loc_write can't write error [%s]", rp -> rp_line)); retval = rp -> rp_val; break; } (void) fclose (ifp); return (retval); }