|
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); }