|
|
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 c
Length: 15745 (0x3d81)
Types: TextFile
Names: »c-P2toRFC.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Format/rfc1148/c-P2toRFC.c«
/* c-P2toRfc.c: rfc987(P2toRFC) filter channel */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Format/rfc1148/RCS/c-P2toRFC.c,v 5.0 90/09/20 16:01:38 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Format/rfc1148/RCS/c-P2toRFC.c,v 5.0 90/09/20 16:01:38 pp Exp Locker: pp $
*
* $Log: c-P2toRFC.c,v $
* Revision 5.0 90/09/20 16:01:38 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
#include "retcode.h"
#include "qmgr.h"
#include "q.h"
#include "prm.h"
#include "chan.h"
#include "ap.h"
#include "dr.h"
#include <isode/cmd_srch.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <isode/usr.dirent.h>
extern char *mquedir;
extern char *quedfldir;
extern char *chndfldir;
extern char *cont_p2, *hdr_p2_bp, *hdr_p22_bp, *hdr_822_bp, *hdr_ipn_bp;
extern void rd_end(), sys_init(), or_myinit(), err_abrt();
extern int convertresult;
CHAN *mychan;
char *this_msg = NULL, *this_chan = NULL;
static struct type_Qmgr_DeliveryStatus *process ();
static int initialise ();
static int filterMsg();
static int x40084;
static int doFilter();
static int link_rest();
static int security_check ();
static void dirinit ();
static struct type_Qmgr_DeliveryStatus *new_DeliveryStatus();
static ADDR *getnthrecip ();
int fatal;
int order_pref;
extern int ap_outtype;
/* \f
*/
/* main routine */
main (argc, argv)
int argc;
char **argv;
{
sys_init(argv[0]);
or_myinit();
dirinit ();
#ifdef PP_DEBUG
if (argc>1 && (strcmp(argv[1],"debug") == 0))
debug_channel_control(argc,argv,initialise,process,NULLIFP);
else
#endif
channel_control (argc, argv, initialise, process,NULLIFP);
}
/* \f
*/
/* routine to move to correct place in file system */
static void dirinit ()
{
if (chdir (quedfldir) < 0)
err_abrt (RP_LIO, " Unable to change directory to '%s'",
quedfldir);
}
/* \f
*/
/* channel initialise routine */
static int initialise (arg)
struct type_Qmgr_Channel *arg;
{
char *name = NULL;
name = qb2str(arg);
if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
PP_OPER(NULLCP,
("Chans/rfc987 : Channel '%s' not known",name));
if (name != NULL) free(name);
return NOTOK;
}
order_pref = CH_USA_PREF;
ap_outtype = AP_PARSE_SAME;
if (mychan->ch_info != NULLCP &&
lexequ (mychan->ch_info, "uk") == 0) {
order_pref = CH_UK_PREF;
ap_outtype |= AP_PARSE_BIG;
}
/* check if a rfc987 channel */
if (name != NULL) free(name);
ap_use_percent();
ap_norm_all_domains();
return OK;
}
/* \f
*/
/* routine to check if allowed to rfc987 filter this message */
static int security_check (msg)
struct type_Qmgr_ProcMsg *msg;
{
char *msg_file = NULL, *msg_chan = NULL;
int result;
result = TRUE;
msg_file = qb2str (msg->qid);
msg_chan = qb2str (msg->channel);
if ((mychan == NULLCHAN) || (strcmp(msg_chan,mychan->ch_name) !=0)) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 channel err: '%s'",msg_chan));
result = FALSE;
}
if (msg_file != NULL) free(msg_file);
if (msg_chan != NULL) free(msg_chan);
return result;
}
/* \f
*/
/* routine called to do rfc987 filter */
static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg *arg;
{
struct prm_vars prm;
Q_struct que;
ADDR *sender = NULL;
ADDR *recips = NULL;
int rcount, first_failureDR, retval;
struct type_Qmgr_UserList *ix;
ADDR *adr;
char *error = NULLCP;
bzero((char *) &que,sizeof(que));
first_failureDR = TRUE;
delivery_init(arg->users);
delivery_setall(int_Qmgr_status_messageFailure);
if (security_check(arg) != TRUE)
return deliverystate;
if (this_msg != NULL) free(this_msg);
if (this_chan != NULL) free(this_chan);
this_msg = qb2str(arg->qid);
this_chan = qb2str(arg->channel);
PP_LOG(LLOG_NOTICE,
("Chans/rfc987 filtering msg '%s' through '%s'",this_msg, this_chan));
if (rp_isbad(rd_msg(this_msg,&prm,&que,&sender,&recips,&rcount))) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 rd_msg err: '%s'",this_msg));
rd_end();
return delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't read message");
}
/* check each recipient for processing */
for (ix = arg->users; ix; ix = ix->next) {
if ((adr = getnthrecip(&que,ix->RecipientId->parm)) == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 : failed to find recipient %d of msg '%s'",ix->RecipientId->parm, this_msg));
delivery_setstate(ix->RecipientId->parm,
int_Qmgr_status_messageFailure,
"Unable to find specified recipient");
continue;
}
switch (chan_acheck(adr, mychan, 1, (char **)NULL)) {
case OK:
if (filterMsg(this_msg,adr,&que, &error) == NOTOK) {
if (convertresult == NOTOK) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc1138 : completely failed to filter msg '%s' for recip '%d' on channel '%s'. Sending a DR",
this_msg, adr->ad_no, this_chan));
set_1dr(&que, adr->ad_no,
DRR_CONVERSION_NOT_PERFORMED,
DRD_CONTENT_SYNTAX_ERROR,
(error == NULLCP) ? "Unable to parse the p2 header" : error);
delivery_set(adr->ad_no,
(first_failureDR == TRUE) ? int_Qmgr_status_negativeDR : int_Qmgr_status_failureSharedDR);
first_failureDR = FALSE;
} else {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 : failed to filter msg '%s' for recip '%d' on channel '%s'",this_msg, adr->ad_no, this_chan));
delivery_setstate(adr->ad_no,
int_Qmgr_status_messageFailure,
(error == NULLCP) ? "Problems doing 1138 conversion" : error);
}
} else {
/* CHANGE update adr->ad_rcnt in struct and in file */
adr->ad_rcnt++;
wr_ad_rcntno(adr,adr->ad_rcnt);
delivery_set(adr->ad_no,
int_Qmgr_status_success);
}
break;
default:
break;
}
if (error != NULLCP) {
free(error);
error = NULLCP;
}
}
if (rp_isbad(retval = wr_q2dr(&que, this_msg))) {
PP_LOG(LLOG_EXCEPTIONS,
("%s wr_q2dr failure '%d'",mychan->ch_name,retval));
delivery_resetDRs(int_Qmgr_status_messageFailure);
}
rd_end();
return deliverystate;
}
/* \f
*/
static int filterMsg (msg,recip,qp, ep)
/* return OK if managed to filter msg through mychan for recip */
char *msg;
ADDR *recip;
Q_struct *qp;
char **ep;
{
char *origdir = NULL,
*newdir = NULL;
int result = OK;
struct stat statbuf;
if (qid2dir(msg, recip, TRUE, &origdir) != OK) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 original directory not found for recipient %d of message '%s'",recip->ad_no, msg));
*ep = strdup("source directory not found");
result = NOTOK;
}
/* temporary change to get new directory name */
recip->ad_rcnt++;
if ((result == OK)
&& (qid2dir(msg, recip, FALSE, &newdir) != OK)) {
PP_LOG(LLOG_EXCEPTIONS,
("Chans/rfc987 couldn't construct new directory for recipient '%d' of message '%s'",recip->ad_no, msg));
*ep = strdup("Unable to construct destination directory");
result = NOTOK;
}
recip->ad_rcnt--;
if ((result == OK)
&& (stat(newdir, &statbuf) == OK)
&& ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
/* directory already exists and so filter already done */
if (origdir != NULL) free(origdir);
if (newdir != NULL) free(newdir);
return OK;
}
if (qp -> cont_type == NULL
|| *(qp -> cont_type) == '\0')
x40084 = -1;
else
x40084 = (lexequ(qp->cont_type, cont_p2) == 0) ? TRUE : FALSE;
if ((result == OK) && (doFilter(origdir,newdir,msg,
qp, ep)!= OK))
result = NOTOK;
if (origdir != NULL) free(origdir);
if (newdir != NULL) free(newdir);
return result;
}
/* \f
*/
char olddir[FILNSIZE],
newdir[FILNSIZE],
xtra_822hdrs[FILNSIZE];
int *dir_flags = NULL,
num_dir_flags = 0,
dirlevel = 0;
#define INC 5
static void resize_dir_flags()
{
num_dir_flags += INC;
if (dir_flags == NULL)
dir_flags = (int *) calloc((unsigned int)num_dir_flags, sizeof(int));
else
dir_flags = (int *) realloc( (char *) dir_flags,
(unsigned) (num_dir_flags * sizeof(int)));
}
static int is822hdrfile(file)
char *file;
{
char buf[LINESIZE];
FILE *fp;
(void) sprintf(xtra_822hdrs, "%s/%s", olddir, file);
if ((fp = fopen(xtra_822hdrs,"r")) == NULL)
{
PP_SLOG(LLOG_EXCEPTIONS, xtra_822hdrs,
("Can't open file"));
return FALSE;
}
if (fgets (buf, LINESIZE - 1, fp) == NULL)
{
PP_DBG (("Null file '%s'",xtra_822hdrs));
fclose(fp);
return FALSE;
}
buf [strlen(buf) - 1] = '\0'; /* remove \n */
if (lexnequ (buf, "RFC-822-HEADERS:",
strlen("RFC-822-HEADERS:")) != 0)
{
fclose (fp);
return FALSE;
}
fclose(fp);
return TRUE;
}
static int is_xtra_822hdrs(entry)
struct dirent *entry;
{
if ((strncmp(entry->d_name,"1.",2) == 0)
&& (is822hdrfile(entry->d_name) == TRUE)) {
(void) sprintf(xtra_822hdrs, "%s/%s", olddir, entry->d_name);
return 1;
}
return 0;
}
static char *get_xtra_822hdrs(dir)
char *dir;
{
int num;
struct dirent **namelist;
num = _scandir(dir, &namelist, is_xtra_822hdrs, NULL);
if (num == 0) {
dir_flags[dirlevel] = FALSE;
return NULLCP;
} else {
dir_flags[dirlevel] = TRUE;
return xtra_822hdrs;
}
}
extern char *ia5_bp;
static doFilter (orig, new, msg, qp, ep)
/* filters orig directory through mychan to new directory */
char *orig,
*new,
*msg;
Q_struct *qp;
char **ep;
{
char hdrp2[FILNSIZE],
hdr822[FILNSIZE], *ipn_body;
int result = OK;
struct stat statbuf;
char buf[BUFSIZ];
(void) sprintf(newdir, "%s/%s/tmp.%s",
mquedir, msg, mychan->ch_name);
if (stat(newdir, &statbuf) == OK) {
char *cmd_line;
/* exists so remove it */
cmd_line = malloc((unsigned) (strlen("rm -rf ") +
strlen(newdir) + 1));
sprintf(cmd_line, "rm -rf %s", newdir);
system(cmd_line);
if (cmd_line != NULL) free(cmd_line);
}
if (mkdir(newdir, 0777) != OK) {
PP_SLOG(LLOG_EXCEPTIONS, newdir,
("Can't make directory"));
(void) sprintf(buf,
"Failed to make temp directory '%s'",
newdir);
*ep = strdup(buf);
result = NOTOK;
}
if (result == OK) {
/* filter from orig to newdir */
LIST_BPT *ix = mychan -> ch_bpt_in;
ipn_body = NULLCP;
if (x40084 == -1) {
while (ix != NULLIST_BPT) {
sprintf(hdrp2,"%s/%s",orig, ix -> li_name);
if (stat(hdrp2, &statbuf) == OK) {
if (lexequ(ix -> li_name, hdr_p2_bp) == 0)
x40084 = TRUE;
else if (lexequ(ix -> li_name, hdr_p22_bp) == 0)
x40084 = FALSE;
break;
}
ix = ix -> li_next;
}
if (ix == NULLIST_BPT) {
/* try for ipn hdr */
sprintf(hdrp2, "%s/%s", orig, hdr_ipn_bp);
if (stat(hdrp2, &statbuf) != OK) {
PP_OPER(NULLCP,
("Format/P2toRFC : cannot find p2 hdr"));
(void) sprintf (buf,
"Cannot find p2 hdr");
*ep = strdup(buf);
return NOTOK;
}
}
} else {
sprintf (hdrp2, "%s/%s",
orig,
(x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
if (stat(hdrp2, &statbuf) != OK) {
/* try for ipn hdr */
sprintf(hdrp2, "%s/%s", orig, hdr_ipn_bp);
if (stat(hdrp2, &statbuf) != OK) {
PP_OPER(NULLCP,
("Format/P2toRFC : cannot find p2 hdr"));
(void) sprintf (buf,
"Cannot find p2 hdr");
*ep = strdup(buf);
return NOTOK;
}
}
}
sprintf(hdr822, "%s/1.%s", newdir, ia5_bp);
ipn_body = strdup(hdr822);
sprintf(hdr822,"%s/%s",newdir,hdr_822_bp);
sprintf(olddir,"%s",orig);
dirlevel = 0;
resize_dir_flags();
result = P2toRFC(hdrp2,get_xtra_822hdrs(orig),qp,
hdr822,ipn_body,ep,x40084);
if (ipn_body) free(ipn_body);
fatal = FALSE;
link_rest(orig, ep);
if (fatal == TRUE)
result = NOTOK;
/* if success rename newdir to new */
if ((result == OK) && (rename(newdir,new) == -1)) {
PP_SLOG(LLOG_EXCEPTIONS, "rename",
("Can't rename directory '%s' to '%s'",
newdir, new));
(void) sprintf (buf,
"Unable to rename temp dir from '%s' to '%s'",
newdir, new);
*ep = strdup(buf);
result = NOTOK;
}
}
return result;
}
/* \f
*/
/* link rest across from orig to newdir */
/* may have to do some renumbering if 1.ia5 is extra headers */
/* origdir and newdir are set to current dirlevel of directories */
char *linkerror = NULLCP;
static int do_link(entry)
struct dirent *entry;
{
struct stat statbuf;
struct dirent **namelist;
int num;
char oldfullname[FILNSIZE],
newfullname[FILNSIZE],
*ix;
if ((strcmp(entry->d_name,".") == 0)
|| (strcmp(entry->d_name,"..") == 0))
return 0;
if ((dir_flags[dirlevel] == TRUE)
&& (strncmp(entry->d_name,"1.",2) == 0))
/* already done so ignore */
return 0;
if (strcmp(entry->d_name,
(x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp) == 0)
/* already dealt with */
return 0;
(void) sprintf(oldfullname, "%s/%s",olddir,entry->d_name);
/* create new filename */
if (isdigit(*(entry->d_name))
&& (dir_flags[dirlevel] == TRUE)) {
/* need to alter number (decrement) */
ix = index(entry->d_name,'.');
*ix = '\0';
num = atoi(entry->d_name);
*ix = '.';
sprintf(newfullname,"%s/%d%s",newdir,--num,ix);
} else
/* just copy */
sprintf(newfullname,"%s/%s",newdir,entry->d_name);
if ((stat(oldfullname,&statbuf) == OK)
&& ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
/* directory so do scandir on it */
char hdrp2[FILNSIZE],
hdr822[FILNSIZE];
struct stat statbuf;
if (mkdir(newfullname, 0777) != OK) {
PP_SLOG(LLOG_EXCEPTIONS, newfullname,
("Can't make directory"));
exit(-1);
}
dirlevel++;
if (dirlevel >= num_dir_flags)
resize_dir_flags();
sprintf(olddir, "%s", oldfullname);
sprintf(newdir, "%s", newfullname);
/* deal with hdr.p2 in this directory if there */
sprintf(hdrp2,"%s/%s",olddir,
(x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
if (stat(hdrp2, &statbuf) == OK) {
sprintf(hdr822,"%s/%s",
newdir, hdr_822_bp);
if (P2toRFC(hdrp2,get_xtra_822hdrs(olddir),
(Q_struct *) NULL,
hdr822, NULLCP,
&linkerror, x40084) != OK) {
fatal = TRUE;
return 0;
}
} else {
PP_OPER(NULLCP,
("Format/P2toRFC : cannot find p2 hdr '%s' for forwarded msg",hdrp2));
fatal = TRUE;
return 0;
}
num = _scandir(olddir,&namelist, do_link, NULL);
/* rewind newdir and olddir */
ix = rindex(olddir,'/');
*ix = '\0';
ix = rindex(newdir,'/');
*ix = '\0';
dirlevel--;
} else
/* just link */
if (link(oldfullname, newfullname) == -1) {
PP_SLOG(LLOG_EXCEPTIONS, "link",
("Can't link from '%s' to '%s'",oldfullname,newfullname));
exit(-1);
}
return 0;
}
static int link_rest(orig, ep)
char *orig;
char **ep;
{
int num;
struct dirent **namelist;
num = _scandir(orig,&namelist, do_link, NULL);
if (linkerror != NULLCP) {
if (*ep == NULLCP)
*ep = linkerror;
else
free(linkerror);
linkerror = NULLCP;
}
}
/* \f
*/
/* auxilary routines to extr<act from lists */
static ADDR *getnthrecip(que, num)
Q_struct *que;
int num;
{
ADDR *ix = que->Raddress;
int icount = 1;
if (num == 0)
return que->Oaddress;
while ((ix != NULL) && (icount++ < num))
ix = ix->ad_next;
return ix;
}
void advise (what, fmt, a, b, c, d, e, f, g, h, i, j)
char *what,
*fmt,
*a,
*b,
*c,
*d,
*e,
*f,
*g,
*h,
*i,
*j;
{
(void) fflush (stdout);
fprintf (stderr, "RFCtoP2 test");
fprintf (stderr, fmt, a, b, c, d, e, f, g, h, i, j);
if (what)
(void) fputc (' ', stderr), perror (what);
else
(void) fputc ('\n', stderr);
(void) fflush (stderr);
}
/* VARARGS 2 */
void adios (what, fmt, a, b, c, d, e, f, g, h, i, j)
char *what,
*fmt,
*a,
*b,
*c,
*d,
*e,
*f,
*g,
*h,
*i,
*j;
{
advise (what, fmt, a, b, c, d, e, f, g, h, i, j);
_exit (1);
}