|
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 s
Length: 8858 (0x229a) Types: TextFile Names: »submit.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Src/submit/submit.c«
/* submit.c: the mail enqueuer */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/submit.c,v 5.0 90/09/20 16:23:12 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/submit.c,v 5.0 90/09/20 16:23:12 pp Exp Locker: pp $ * * $Log: submit.c,v $ * Revision 5.0 90/09/20 16:23:12 pp * rcsforce : 5.0 public release * */ #include "head.h" #include "prm.h" #include "q.h" #include <varargs.h> #include <sys/stat.h> #include <sys/time.h> #include <signal.h> #include <pwd.h> #include <isode/cmd_srch.h> /* -- externals -- */ extern char *msg_unique, /* unique part of msg queue name */ *mgt_inhost, *qmgr_hostname, *rcmd_srch(), *quedfldir, /* dir w/mail queue directories */ auth2submit_msg[]; extern int mgt_adtype, adr_count, protocol_mode; extern ADDR *ad_originator, *ad_recip; extern struct passwd *getpwuid(); extern long msg_size; extern CHAN *ch_inbound; extern CMD_TABLE qtbl_mt_type[]; /* -- globals -- */ char *username; /* login name of usr running me */ int effecid, /* id providing access priviliges */ privileged, /* am I a priveledged user ? */ userid, /* id of user running me */ accept_all, notrace, end_of_file; /* eof encountered on stdin */ Q_struct Qstruct; /* -- static variables -- */ static struct prm_vars Prm; static int qmgr_fd = NOTOK; static int log_msgtype; /* -- local routines -- */ void err_abrt(); void pro_reply(); static int priv_user(); static void _pro_reply(); static void dir_init(); static void done(); static void msg_init(); static void set_qadr(); static void user_init(); /* -------------------- Main Routine ---------------------------------- */ /* ARGSUSED */ main (argc, argv) int argc; char **argv; { int retval; (void) umask (0); sys_init (argv[0]); user_init(); dir_init(); or_myinit(); fmt_init(); ap_use_percent(); (void) signal (SIGPIPE, done); /* temp hack */ (void) signal(SIGSEGV, SIG_DFL); (void) signal (SIGBUS, SIG_DFL); while (!end_of_file) { /* Reset various parameters */ msg_init(); protocol_mode = 1; /* Read the parameter settings for a Message */ if (rp_isbad (retval = rd_prm_info (&Prm))) { if (end_of_file) continue; err_abrt (retval, "bad parameters"); } else pro_reply (RP_OK, "Got the parameters"); /* Read the queue structure */ if (rp_isbad (retval = rd_q_info (&Qstruct))) err_abrt (retval, "Bad queue read"); /* Perform management functions on parameters */ if (rp_isbad (retval = cntrl_mgt (&Prm, &Qstruct))) err_abrt (retval, "Bad parameter settings"); /* Perform management functions on the queue */ if (rp_isbad (retval = q_mgt (&Qstruct))) err_abrt (retval, "Bad queue parameter settings"); pro_reply (RP_OK, "Starting fine, sender please"); /* Validate the sender */ validate_sender(); pro_reply (RP_AOK, "Continuing fine, addresses please"); /* Validate the Recipients */ validate_recip(); /* Authorisation - main routines */ auth_start(); /* Sets the Qstruct's Originator and Recipient fields */ set_qadr(); time_mgt(); /* Initialize to the queue directory for output */ winit_q(); /* if (DMPDU) parse DR from incoming channel else if (body) splat the body into a file */ log_msgtype = Qstruct.msgtype; switch (Qstruct.msgtype) { case MT_DMPDU: pro_reply (RP_AOK, "Addresses ok, DR info please"); if (rp_isbad (retval = gen_io2dr())) { if (end_of_file) continue; err_abrt (retval, "Bad DR struct"); } Qstruct.msgtype = MT_UMPDU; break; case MT_PMPDU: msg_size = Qstruct.msgsize; break; default: pro_reply (RP_AOK, "Addresses ok, text please"); /* For fast rejection of a message containing invalid body parts or where message size is too big, the auth_content() checks should go into txt_input(). But for now ... */ txt_input (notrace == 0 && ch_inbound -> ch_access == CH_MTA); break; } protocol_mode = 0; /* end of protocol phase */ /* finish authorisation tests on message size/body parts and perform channel binding */ if (rp_isbad (retval = auth_finish())) if (!accept_all) err_abrt (retval, "%s : %s", "At least one recipient fails authorisation", auth2submit_msg); check_crits (&Qstruct); check_conversions (&Qstruct); /* Generate the appropriate Delivery Notifications */ switch (Qstruct.msgtype) { case MT_PMPDU: gen_probedr(); break; default: gen_ndr(); break; } write_q (&Qstruct, &Prm); move_q(); pro_reply (RP_MOK, "Submitted & queued (%s)", msg_unique); /* generate authorisation statistics logs now that msg_unique is known */ auth_log(); /* Tell qmgr */ if (qmgr_fd == NOTOK) qmgr_fd = qmgr_start (qmgr_hostname); if (qmgr_fd != NOTOK) (void) message_send (qmgr_fd, msg_unique, &Prm, &Qstruct, ad_originator, ad_recip, adr_count); if (ch_inbound != NULL && ch_inbound->ch_access == CH_MTS) PP_NOTICE (("<<< local %s %s %s %s %s", rcmd_srch(log_msgtype, qtbl_mt_type), msg_unique, ch_inbound -> ch_name, username, mgt_inhost)); else PP_NOTICE (("<<< remote %s %s %s %s", rcmd_srch(log_msgtype, qtbl_mt_type), msg_unique, ch_inbound -> ch_name, mgt_inhost == NULLCP ? "<unknown-host>" : mgt_inhost)); } if (qmgr_fd != NOTOK) (void) qmgr_end (qmgr_fd); PP_TRACE (("Submit normal end")); exit (RP_OK); } /* -------------------- Static Routines ------------------------------- */ /* Get information on the incomming channel calling submit */ static void user_init() { register struct passwd *pw; PP_LOG (LLOG_DEBUG, ("submit/user_init()")); privileged = FALSE; userid = getuid(); effecid = geteuid(); if ((pw = getpwuid (userid)) == NULL) err_abrt (RP_LIO, "No login for UID %d, call Support.", userid); endpwent(); username = strdup (pw->pw_name); if (priv_user (userid, effecid) == TRUE) privileged = TRUE; if (pp_setuserid() == NOTOK) err_abrt (RP_LIO, "Unable to set user id"); } static int priv_user (id, eid) int id, eid; { struct passwd *pwd; extern char *pplogin; if (id == 0 || eid == id) return TRUE; if ((pwd = getpwnam (pplogin)) == (struct passwd *)0) return FALSE; if (id == pwd -> pw_uid) return TRUE; return FALSE; } /* chdir */ static void dir_init() { /* cd into the queue directory */ if (chdir (quedfldir) < 0) err_abrt (RP_LIO, "Unable to change directory. '%s'", quedfldir); } /* Initialise a msg */ static void msg_init() { msg_unique = NULLCP; /* for logging failed messages */ msg_mgt(); ad_init(); } static void set_qadr() { extern ADDR *ad_recip, *ad_originator; PP_DBG (("submit/set_qadr()")); Qstruct.Raddress = ad_recip; Qstruct.Oaddress = ad_originator; } /* -------------------- Reply Routines -------------------------------- */ #ifdef lint /*VARARGS2*/ void pro_reply (code, fmt) int code; char *fmt; { pro_reply (code, fmt); } #else void pro_reply (va_alist) va_dcl { va_list ap; int code; va_start(ap); code = va_arg (ap, int); _pro_reply (code, ap); va_end (ap); } static void _pro_reply (code, ap) int code; va_list ap; { char buffer[BUFSIZ]; register char *errchar = NULLCP; if (rp_isbad (code)) switch (code) { case RP_HUH: /* not if it was a user error */ case RP_PARM: case RP_USER: case RP_PARSE: case RP_BHST: case RP_NAUTH: break; default: errchar = " "; break; } _asprintf (buffer, errchar, ap); PP_LOG (rp_isbad (code) ? LLOG_EXCEPTIONS : LLOG_PDUS|LLOG_TRACE, ("submit/pro_reply(%s) '%s'", rp_valstr (code), buffer)); (void) fputc (code, stdout); (void) fputs (buffer, stdout); (void) fputc ('\n', stdout); (void) fflush (stdout); } #endif /* --------------- (err_) GENERAL ERROR-HANDLING ----------------------- */ #ifdef lint /*VARARGS2*/ void err_abrt (code, fmt) int code; char *fmt; { clear_q(); pro_reply (code, fmt); } #else void err_abrt (va_alist) /* terminate the process */ va_dcl { va_list ap; int code; va_start (ap); code = va_arg (ap, int); PP_TRACE (("err_abrt (%d)", code)); _pro_reply (code, ap); va_end (ap); done (-1); /* pass the reply code to caller */ } #endif static void done (n) int n; { PP_TRACE (("done (%d)", n)); clear_q(); exit (n); }