|
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 m
Length: 31283 (0x7a33) Types: TextFile Names: »mu.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Tools/mu/mu.c«
/* mu.c MTS user interface */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/mu/RCS/mu.c,v 5.0 90/09/20 16:29:04 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Tools/mu/RCS/mu.c,v 5.0 90/09/20 16:29:04 pp Exp Locker: pp $ * * $Log: mu.c,v $ * Revision 5.0 90/09/20 16:29:04 pp * rcsforce : 5.0 public release * */ #include "head.h" #include "util.h" #include "q.h" #include "prm.h" #include <isode/cmd_srch.h> #include "tb_prm.h" #include "tb_q.h" #include "tb_a.h" #include "tb_dr.h" #include <signal.h> #include <isode/usr.dirent.h> #include <sys/stat.h> #include "argh.h" /* jct only */ /* That's enough #includes - ed */ /* tailor'ed directory */ extern char *cmddfldir; #define DEFAULT_FILENAME "mu.defaults" #define MAXNAME_LENGTH 200 #define MAXARG_COUNT 200 #define COMMENTCHAR '#' #define TOKENCHAR '$' #define REPEATCHAR '*' #define FILEMARKCHAR '*' #define DISP_INDENT 2 #define YES_STRING "Yy" #define NO_STRING "Nn" #define THREE_BAGS_FULL_STRING "" /* joke */ #define CONFIRM_STRING "Confirm ( Y/N ) " /* ------ from : ut_msg.c: library of routines to read a message directory struct */ #define NULLDIR ((DIR*)0) #define NULLDCT ((struct dirent *)0) extern int errno; extern int fcmp(); static DIR *ST_dir = NULLDIR; static char *ST_array[LOTS]; static char *ST_name = NULLCP; static int ST_curr = NULL; static int ST_level = NULL; static int ST_no = NULL; static int basedir_len; static int UM_rfile (), UM_push (), UM_isdir (), UM_array_free (); static struct dirent *UM_readdir(), *UM_pop(); /* ------ from : ut_msg.c: library of routines to read a message directory struct */ void advise(); void adios(); extern cleanquit(); struct argdef arg[] = { /* program specific flag definitions */ /* flag function type match */ "default", NULL, '1', 0, "file", NULL, 'm', 0, "value", NULL, 'm', 0, "body", NULL, 'm', 0, "tree", NULL, '1', 0, "confirm", NULL, '0', 0, "nofix", NULL, '0', 0, "prompt", NULL, '2', 0, "group", NULL, '1', 0, "logfile", NULL, '1', 0, "help", show_args, '0', 0, "-", show_args, '0', 0, "!", NULL, '0', 0, "0", NULL, '0', 0, "1", NULL, '0', 0, "2", NULL, '0', 0, "3", NULL, '0', 0, "4", NULL, '0', 0, "5", NULL, '0', 0, "", NULL, '?', 0 /* "" is 'others' list, also terminates structure array */ }; /* Other global variables */ static struct prm_vars prm; static struct Qstruct q; ADDR *ad_originator; /* address of sender */ ADDR *ad_recipient; /* recipient list */ RP_Buf r,*rp = &r; /* reply value structure */ int debug[6]={0,0,0,0,0,0}; /* interactive debug flags */ int nest_level=0; /* to display level of recursion */ int use_termcap = FALSE; int confirm_input = FALSE; int fix_input = TRUE; FILE *muout=stdout; /* progress messages to... */ char *getcwd(); /* not used */ /* In addition to the LLOG_TRACE, LLOG_DEBUG calls associated with debug[0], debug[1] shown below, there are other LLOG_FATAL and LLOG_EXCEPTIONS calls. Note that list_args and show_args ( in argh.c ) do not generate LLOG events. debug[?] function 0 log to muout progress messages, and PPLOG( LLOG_TRACE ...) 1 log to muout command files as they are processed, and PPLOG( LLOG_DEBUG ...) 2 list to muout body part files as they are io_tdata'ed 3 list to muout structures prior to submit io_ calls 4 abort prior to submit io_ calls 5 append to logfile rather than overwrite */ /* ----------------------------------------------------------------- */ main (argc, argv) int argc; char **argv; { sys_init (argv[0]); signal(SIGINT,cleanquit); start_screen(); msg_init(); /* initialise message structures */ in_all(argc,argv); do_all(argc,argv); finish_screen(); if (muout != stdout) fclose(muout); exit(0); } /* ----------------------------------------------------------------- */ in_all(argc, argv) /* input from original or constructed command line */ /* CALLED RECURSIVELY */ int argc; char **argv; { int scan_counter; if (debug[0]) { fprintf(muout,"in_all nest_level %d\n",nest_level); PP_LOG (LLOG_TRACE,("mu: in_all nest_level %d",nest_level)); } /* printf("argc=%d argv=%h\n",argc,argv); */ scan_counter=scan_args(argc,argv); /* prep_args() called automatically */ get_debug(scan_counter); process_args(argv,scan_counter); } /* ----------------------------------------------------------------- */ do_all(argc, argv) /* all post-input operations */ int argc; char **argv; { if (debug[0]){ list_args(muout,"default"); list_args(muout,"logfile"); list_args(muout,"file"); list_args(muout,"value"); list_args(muout,"body"); list_args(muout,"tree"); list_args(muout,"confirm"); list_args(muout,"nofix"); /* list_args(muout,"prompt"); list_args(muout,"group"); */ list_args(muout,""); } call_args(argc,argv,muout); /* pass output file pointer */ if (ad_originator == NULLADDR) adios("","No originator specified"); /* ... and abort */ if (ad_recipient == NULLADDR) adios("","No recipient specified"); /* ... and abort */ if( debug[3] ) print_structures(); if( !debug[4] ) submit_message(argv); return; } /* ----------------------------------------------------------------- */ process_args(argv,scan_counter) char **argv; int scan_counter; { FILE *fd; static char default_filename[MAXNAME_LENGTH] = DEFAULT_FILENAME; char *argvtemp[MAXARG_COUNT]; char buf[LOTS]; char *p, *p_end; int i,n,of,dummy; if (scan_counter == 1) { /* can override mu.defaults from command line only */ if(p=nextc_arg("default",scan_counter,&n,&of)) strcpy(default_filename,p); else { if ((fd = fopen(default_filename,"r")) == NULL ) sprintf(default_filename,"%s/%s",cmddfldir,DEFAULT_FILENAME); else fclose(fd); } read_file(default_filename); /* into param_, queue_structure */ } /* read all -file arguments */ while (p=nextc_arg("file",scan_counter,&n,&of)) { read_file(p); /* into param_, queue_,addr_structure */ } /* scan all -body arguments */ while (p=nextc_arg("body",scan_counter,&n,&of)) { try_file(p); /* open and check file length */ } /* at least one call to next_arg/nextc_arg with different argument is necessary before looping on "body" again; "tree" will do nicely ... */ /* scan all -tree arguments */ while (p=nextc_arg("tree",scan_counter,&n,&of)) { try_directory(p); /* check that it exists */ } /* similarly... at least one call to next_arg/nextc_arg with different argument is necessary before looping on "tree" again; "value" will do nicely ... */ for (n=0,of=0;(p = nextc_arg("value",scan_counter,&n,&of)) != NULL;) { sprintf (buf, "%s", p); i = 1; while (of-i) { p = nextc_arg("value",scan_counter,&dummy,&dummy); p_end = index( buf, '\0' ); sprintf (p_end, " %s", p); /* i.e. concatenate parameters */ i++; } /* this messy construction is necessary to put argvtemp in proper format */ of = str2arg (buf, MAXARG_COUNT, argvtemp, NULLCP); if ( debug[0] ) { dump_args(of,argvtemp); } parse_txt(of,argvtemp); } return(TRUE); } /* ----------------------------------------------------------------- */ get_debug(scan_counter) /* check for action flags */ { char deb[2]; /* very short string */ char *p; int i,n,of; for(i=0;i<=5;i++) { deb[0]=('0'+i); deb[1]='\0'; if (nextc_arg(deb,scan_counter,&n,&of)) { debug[i] = 1; if ( debug[0] ) { fprintf(muout,"debug flag %s set\n", deb); PP_LOG (LLOG_TRACE,("mu: debug flag %s set", deb)); } } } if (nextc_arg("nofix",scan_counter,&n,&of)) if ( debug[0] ) { fprintf(muout,"nofix set\n"); PP_LOG (LLOG_TRACE,("mu: nofix set")); } fix_input=FALSE; if (nextc_arg("confirm",scan_counter,&n,&of)) if ( debug[0] ) { fprintf(muout,"confirm set\n"); PP_LOG (LLOG_TRACE,("mu: confirm set")); } confirm_input=TRUE; if (p=nextc_arg("logfile",scan_counter,&n,&of)) { if ( debug[0] ) { fprintf(muout,"logfile set to %s\n", p); PP_LOG (LLOG_TRACE,("mu: logfile set to %s", p)); } if (muout != stdout) fclose(muout); if ( debug[5] ) { if ((muout = fopen(p,"a")) == NULL ) { advise("","unable to append to %s",p); muout = stdout; /* and send to screen */ } } else { if ((muout = fopen(p,"w")) == NULL ) { advise("","unable to write to %s",p); muout = stdout; } } } } /* ----------------------------------------------------------------- */ read_file(p) /* read file *p */ char *p; { FILE *fd; if (debug[0]) { fprintf(muout,"start read_file : %s\n",p); PP_LOG (LLOG_TRACE,("mu: start read_file : %s",p)); } if ((fd = fopen(p,"r")) == NULL ) { adios("","unable to read %s",p); /* ... and abort */ return; } /* Rather than call rd_prm, rd_q, rd_adr individually, each of which expects to receive a subset of the control parameters, each line is read with txt2buf to command-argument form with str2arg (was sstr2arg) then offered to each of txt2prm, txt2q and txt2adr in turn to see if it is valid for any - if not then an error is reported. */ rd_all(fd); fclose(fd); if (debug[0]) { fprintf(muout,"finish read_file : %s\n",p); PP_LOG (LLOG_TRACE,("mu: finish read_file : %s",p)); } return; } /* ----------------------------------------------------------------- */ try_file(p) /* open, check file length */ char *p; { FILE *fd; long f; char pp[MAXNAME_LENGTH],*r; strcpy(pp,p); if (r=index(pp,FILEMARKCHAR)) { *r = '\0'; strcat(pp,r+1); if (debug[0]) { fprintf(muout,"body part %s FILEMARKCHAR detected : %s\n",p,pp); PP_LOG (LLOG_TRACE,("mu: body part %s FILEMARKCHAR detected : %s",p,pp)); } } if ((fd = fopen(pp,"r")) == NULL ) adios("","unable to read body part %s",pp); fseek(fd,0L,2); /* eof */ if ((f=ftell(fd)) == 0 ) adios("","body part %s is null file",pp); fclose(fd); return; } /* ----------------------------------------------------------------- */ try_directory(p) /* check that it exists */ char *p; { char pp[MAXNAME_LENGTH],*r; strcpy(pp,p); if (r=index(pp,FILEMARKCHAR)) { *r = '\0'; strcat(pp,r+1); if (debug[0]) { fprintf(muout,"directory %s FILEMARKCHAR detected : %s\n",p,pp); PP_LOG (LLOG_TRACE,("mu: directory %s FILEMARKCHAR detected : %s",p,pp)); } } if (dir_rinit(pp) != RP_OK) adios("","cannot initialise directory %s",pp); dir_rend(); return; } /* ----------------------------------------------------------------- */ rd_all (fd) FILE *fd; { char buf[LOTS],copybuf[LOTS]; char *argv[MAXARG_COUNT]; int argc,retval,repeat,repeat_offset,user_input,parse_result; int tokenfound; for (;;) { retval = txt2buf (buf, fd); if (rp_isbad (retval)) return (retval); if(debug[1]) display(buf,nest_level); if (*buf == REPEATCHAR) { repeat = TRUE; repeat_offset = 1; } else { repeat = FALSE; repeat_offset = 0; } for(;;) { /* copy buf to copybuf and check for TOKENCHAR */ user_input=prompt(copybuf,buf,repeat,&tokenfound); if (repeat && !tokenfound) { advise(NULL,"<<%s>>\nerror : no TOKENCHAR(s) in REPEAT line - REPEATCHAR ignored",buf); repeat = FALSE; } if(repeat && !user_input) /* no more user input */ break; strip(copybuf); /* remove trailing spaces */ /* argc = str2arg (copybuf+repeat_offset, 50, argv, " \t\n"); */ argc = str2arg (copybuf+repeat_offset, MAXARG_COUNT, argv, NULLCP); argv[argc] = NULLCP; /* if (debug[0]) { dump_args(argc,argv); } */ if (argc == 0) { /* ignore empty lines */ parse_result=OK; } else { parse_result=parse_txt(argc,argv); /* parse_txt(argc,argv,ftell(fd)); */ } if(repeat || (fix_input && user_input && (parse_result == NOTOK)) ) { continue; } else { break; } } } } /* ----------------------------------------------------------------- */ parse_txt(argc,argv) /* returns OK || NOTOK */ int argc; char **argv; /* long fd_startln; /* for _offset calculations */ { char *p; char buf[LOTS]; char *nargv[MAXARG_COUNT]; int nargc; int retval; if(**argv == COMMENTCHAR) { if (debug[0] && !debug[1]) { /* avoids duplicatation */ arg2vstr(LOTS,LOTS,buf,argv); display(buf,nest_level); } } else if(**argv == FLAGCHAR) { /* dump_args(-1,argv); */ arg2vstr(LOTS,LOTS,buf,argv); /* fflush(muout); fprintf(muout,"muout flushed\n"); */ if (debug[0]) { fprintf(muout,"arg2vstr returns <%s>\n",buf); PP_LOG (LLOG_TRACE,("mu: arg2vstr returns <%s>",buf)); } p=malloc(strlen(buf)+6); sprintf(p,"DUMMY %s",buf); if (debug[0]) { fprintf(muout,"\nin_all RECURSION with %s\n\n",p); PP_LOG (LLOG_TRACE,("mu: in_all RECURSION with %s",p)); } strip(p); /* remove trailing spaces */ /* nargc = str2arg (p, 50, nargv, " \t\n"); */ nargc = str2arg (p, MAXARG_COUNT, nargv, NULLCP); nargv[nargc] = NULLCP; /* if (debug[0]) { dump_args(nargc,nargv); } */ if (nargc != 0) { nest_level++; in_all(nargc,nargv); /* ***** RECURSION ***** */ nest_level--; } } else { retval = txt2prm (&prm, argv, argc); if (rp_isgood(retval) || retval == PRM_END) return(OK); retval = txt2q (&q, argv, argc); if (rp_isgood(retval) || retval == Q_END) return(OK); if (lexequ(argv[0],"Origs") == 0) { if (debug[0]) { fprintf(muout,"Origs in input\n"); PP_LOG (LLOG_TRACE,("mu: Origs in input")); } if (ad_originator == NULLADDR) { /* Only one Origs */ retval = txt2adr (&ad_originator, 0L, argv, argc); if (rp_isgood(retval) || retval == AD_END) return(OK); } } else { retval = txt2adr (&ad_recipient, 0L, argv, argc); if (rp_isgood(retval) || retval == AD_END) return(OK); } /* error if get here */ arg2vstr(LOTS,LOTS,buf,argv); advise(NULL,"error `%s' (retval=%s)",buf,digit_word(retval)); return(NOTOK); } return(OK); } /* ----------------------------------------------------------------- */ print_structures() /* print out result of merge */ { ADDR *ap; fprintf (muout,"-----------------------------------------------------------------\n"); prm2txt (muout,&prm); q2txt (muout,&q); adr2txt (muout,ad_originator,AD_ORIGINATOR); ap = ad_recipient; do { adr2txt (muout,ap,AD_RECIPIENT); ap = ap->ad_next; } while ( ap != NULL ); fprintf (muout,"-----------------------------------------------------------------\n"); } /* ----------------------------------------------------------------- */ int prompt(copybuf,buf,repeat,tokenfound) /* user input to expand embedded TOKENCHAR's */ char *copybuf,*buf; /* buf is original line from file */ int repeat; int *tokenfound; { char *p; char inbuf[LOTS]; int user_input=FALSE; strcpy(copybuf,buf); /* only modify copy */ *tokenfound = FALSE; /* to be tested with repeat */ if( (*buf != COMMENTCHAR) && (index(buf,TOKENCHAR)) ) { for(;;) { /* Loop to allow line re-input if not confirmed */ p=copybuf; while (p = index(p,TOKENCHAR)) { p++; if ( *p == TOKENCHAR ) { /* $$ - do not set tokenfound */ *p = '\0'; strcat(copybuf,p+1); } else { *tokenfound = TRUE; *(--p) = '\0'; printf("\n%s%c ",copybuf,TOKENCHAR); scanfcr(inbuf); /* scanf("%s",inbuf); */ if (repeat && (strlen(inbuf) == 0)) { user_input=FALSE; return(user_input); /* I HATE THIS */ } else { user_input=TRUE; strcat(inbuf,p+1); strcat(p,inbuf); } } } if (user_input && confirm_input) { if (confirm(copybuf)) { break; } else { strcpy(copybuf,buf); continue; /* re-input whole line */ } } else { break; /* confirm_input FALSE or TRUE and confirmed */ } } } return(user_input); } /* ----------------------------------------------------------------- */ scanfcr(inbuf) /* equiv. to scanf("%s",inbuf) with CR only allowed */ char *inbuf; { int i; char c; for(i=0,inbuf[i]='\0';((inbuf[i]=getchar()) != '\n');i++) { } inbuf[i]='\0'; } /* ----------------------------------------------------------------- */ confirm(buf) /* offer confirmation of user input */ char *buf; { int i; char s[10]; for(;;) { printf("\n%s\n\t%s",buf,CONFIRM_STRING); scanfcr(s); if (s[0] == '\0') continue; if (index(YES_STRING,s[0])) { i=TRUE; break; } if (index( NO_STRING,s[0])) { i=FALSE; break; } } return(i); } /* ----------------------------------------------------------------- */ msg_init() { /* prm_init (p); */ q_init(&q); ad_init(); } /* ----------------------------------------------------------------- */ ad_init() /* -- initialise the linked lists -- */ { if (ad_recipient != NULLADDR) adr_tfree (ad_recipient); if (ad_originator != NULLADDR) adr_tfree (ad_originator); ad_originator = NULLADDR; ad_recipient = NULLADDR; } /* ----------------------------------------------------------------- */ submit_message(argv) char **argv; { int type = OK; int offset; char *p,*r; char t[FILNSIZE]; /* for copy of directory specified in -tree */ char dir_fname[FILNSIZE]; char submit_fname[FILNSIZE]; ADDR *ap; if (debug[0]) { fprintf(muout,"submit_message io_init\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_init")); } if(rp_isbad(io_init(rp))) rp_error(rp); if (debug[0]) { fprintf(muout,"submit_message io_wprm\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_wprm")); } if(rp_isbad(io_wprm(&prm,rp))) rp_error(rp); if (debug[0]) { fprintf(muout,"submit_message io_wrq\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_wrq")); } if(rp_isbad(io_wrq(&q,rp))) rp_error(rp); ap = ad_originator; if (debug[0]) { fprintf(muout,"submit_message io_wadr originator %s\n",ap->ad_value); PP_LOG (LLOG_TRACE,("mu: submit_message io_wadr originator %s",ap->ad_value)); } if(rp_isbad(io_wadr(ap,AD_ORIGINATOR,rp))) rp_error(rp); ap = ad_recipient; do { if (debug[0]) { fprintf(muout,"submit_message io_wadr recipient %s\n",ap->ad_value); PP_LOG (LLOG_TRACE,("mu: submit_message io_wadr recipient %s",ap->ad_value)); } if(rp_isbad(io_wadr(ap,AD_RECIPIENT,rp))) rp_error(rp); ap = ap->ad_next; } while ( ap != NULL ); if (debug[0]) { fprintf(muout,"submit_message io_adend\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_adend")); } if(rp_isbad(io_adend(rp))) rp_error(rp); if(((p=next_arg("body",argv)) !=NULL) || ((p=next_arg("tree",argv)) != NULL)) { if (debug[0]) { fprintf(muout,"submit_message io_tinit\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tinit")); } if(rp_isbad(io_tinit(rp))) rp_error(rp); p=next_arg("",argv); /* dummy to clear next_args memory */ if(((p=next_arg("body",argv)) !=NULL) ) { do { if ((r=index(p,FILEMARKCHAR)) == NULL) r=p; else ++r; /* pass pointer just after FILECHARMARK */ if (debug[0]) { fprintf(muout,"submit_message io_tpart file %s\n",r); PP_LOG (LLOG_TRACE,("mu: submit_message io_tpart file %s",r)); } if(rp_isbad(io_tpart(r,FALSE,rp))) rp_error(rp); if (debug[0]) { fprintf(muout,"submit_message io_tdata loop\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tdata loop")); } loop_data(p); /* and transfer file */ if (debug[0]) { fprintf(muout,"submit_message io_tdend\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tdend")); } if(rp_isbad(io_tdend(rp))) { rp_error(rp); } } while(p=next_arg("body",argv)); } p=next_arg("",argv); /* dummy to clear next_args memory */ if(((p=next_arg("tree",argv)) !=NULL) ) { do { strcpy(t,p); /* copy for FILCHARMARK manipulation */ if ((r=index(t,FILEMARKCHAR))) { *r = '\0'; strcat(t,r+1); offset = r-t; /* offset to intended name - just after FILECHARMARK */ } else { offset = 0; } if (debug[0]) { fprintf(muout,"submit_message dir_rinit %s\n",t); PP_LOG (LLOG_TRACE,("mu: submit_message dir_rinit %s",t)); } if ( dir_rinit( t ) != RP_OK ) adios (NULL,"Cannot initialise directory %s\n",t); while (dir_rfile(dir_fname) == RP_OK ) { if (debug[0]) { fprintf(muout,"mu: dir_rfile %s\n",dir_fname); PP_LOG (LLOG_TRACE,("mu: mu/dir_rfile %s",dir_fname)); } strcpy(submit_fname,&dir_fname[offset]); if (debug[0]) { if (offset) { fprintf(muout,"mu: offset %d submitted name io_tpart : %s\n",offset,submit_fname); PP_LOG (LLOG_TRACE,("mu: offset %d submitted name io_tpart : %s",offset,submit_fname)); } } if(rp_isbad(io_tpart(submit_fname,FALSE,rp))) rp_error(rp); if (debug[0]) { fprintf(muout,"submit_message io_tdata loop\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tdata loop")); } loop_data(dir_fname); if (debug[0]) { fprintf(muout,"submit_message io_tdend\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tdend")); } if(rp_isbad(io_tdend(rp))) { rp_error(rp); } } dir_rend(); } while(p=next_arg("tree",argv)); } } if (debug[0]) { fprintf(muout,"submit_message io_tend\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_tend")); } if(rp_isbad(io_tend(rp))) rp_error(rp); if (debug[0]) { fprintf(muout,"submit_message io_end\n"); PP_LOG (LLOG_TRACE,("mu: submit_message io_end")); } if(io_end(type) == NOTOK) rp_error(rp); else { if (debug[0]) { fprintf(muout,"submit_message OK\n"); PP_LOG (LLOG_TRACE,("mu: submit_message OK")); } } return; } /* ----------------------------------------------------------------- */ loop_data(p) char *p; { int length; char buf[LOTS]; FILE *fd; char pp[MAXNAME_LENGTH],*r; strcpy(pp,p); if (r=index(pp,FILEMARKCHAR)) { *r = '\0'; strcat(pp,r+1); } if ((fd = fopen(pp,"r")) == NULL ) adios("","unable to open body part for reading %s",pp); while ( (length=fread(buf,1,LOTS,fd)) ) { if (debug[2]) fwrite(buf,1,length,muout); io_tdata(buf,length); } fclose(fd); } /* ----------------------------------------------------------------- */ rp_error(rp) RP_Buf *rp; { adios (NULL,"RP_ERROR %d %s\n",rp->rp_val,rp->rp_line); } /* ----------------------------------------------------------------- */ display (s,level) char *s; int level; { fprintf(muout,"%*s%s\n",level * DISP_INDENT, "", s); PP_LOG (LLOG_DEBUG,("mu: input line %s", s)); } /* ----------------------------------------------------------------- */ /* VARARGS */ 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; { PP_LOG (LLOG_FATAL,(fmt, a, b, c, d, e, f, g, h, i, j)); advise (what, fmt, a, b, c, d, e, f, g, h, i, j); cleanquit (); } /* ----------------------------------------------------------------- */ /* VARARGS */ 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; { if (muout != stdout) { fprintf (muout, fmt, a, b, c, d, e, f, g, h, i, j); if (what) (void) fputc (' ', muout), perror (what); else (void) fputc ('\n', muout); (void) fflush (muout); } 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); PP_LOG (LLOG_EXCEPTIONS,(fmt, a, b, c, d, e, f, g, h, i, j)); } /* ----------------------------------------------------------------- */ /* ***************** These routines taken from :- ******************* : ut_msg.c : library of routines to read a message directory struct */ dir_rinit (dir) /* was msg_rinit (dir) */ char *dir; { /* Now pass full or relative path for each invocation - unlike msg_rinit */ PP_DBG (("mu: dir_rinit: (%s)", dir)); if (ST_dir) dir_rend(); ST_level = 0; ST_name = malloc (LINESIZE); bzero (ST_name, LINESIZE); /* full path not assumed */ (void) sprintf (ST_name, "%s", dir); if (!UM_isdir (ST_name)) { PP_LOG (LLOG_FATAL,("mu: dir_rinit: %s is not a dir", ST_name)); return (RP_FOPN); } if ((ST_dir = opendir (ST_name)) == NULLDIR) { PP_LOG (LLOG_FATAL,("mu: dir_rinit: unable to open %s", ST_name)); return (RP_FOPN); } basedir_len = strlen(ST_name); return (RP_OK); } /* ----------------------------------------------------------------- */ dir_rfile (buf) /* was msg_rfile (dir) */ char *buf; { char *ptr; PP_DBG (("mu: dir_rfile: (%s)", ST_name)); if (ST_no == NULL) { while (UM_rfile (buf) == RP_OK) { ptr = strdup (buf); ST_array [ST_no] = ptr; ++ST_no; } qsort ((char *)ST_array, ST_no, (sizeof (ST_array[0])), fcmp); } if (ST_curr < ST_no) { (void) strcpy (buf, ST_array[ST_curr]); ++ST_curr; return (RP_OK); } return (RP_DONE); } /* ----------------------------------------------------------------- */ dir_rend() /* was msg_rend (dir) */ { PP_DBG (("mu: dir_rend: (%s)", ST_name)); if (ST_dir) { closedir (ST_dir); ST_dir = NULLDIR; } if (ST_name) { free (ST_name); ST_name = NULLCP; } if (ST_no) UM_array_free(); ST_level = NULL; return (RP_OK); } /* ----------------------------------------------------------------- */ fcmp (f1, f2) register char **f1, **f2; { char *stripedf1, *stripedf2; stripedf1 = (*f1)+basedir_len+1; stripedf2 = (*f2)+basedir_len+1; return recur_fcmp(stripedf1,stripedf2); } /* ----------------------------------------------------------------- */ recur_fcmp(f1,f2) register char *f1, *f2; { /* atoi stops at the first non digit */ int f1digit = atoi(f1); int f2digit = atoi(f2); if (f1digit < f2digit) return -1; else if (f1digit > f2digit) return 1; else { int f1isdir, f2isdir; char *ixf1, *ixf2; /* dificult case may have to recurse */ f1isdir = ((ixf1 = index(f1,'/')) != NULL); f2isdir = ((ixf2 = index(f2,'/')) != NULL); if (f1isdir && f2isdir) return recur_fcmp(++ixf1,++ixf2); return 0; } } /* -------------------------- Static Routines -------------------------- */ static UM_rfile (buf) char *buf; { struct dirent *dp; if (ST_dir == NULLDIR) { PP_LOG (LLOG_FATAL,("mu: UM_rfile: opendir not performed")); return (RP_DONE); } dp = UM_readdir (NULLCP); if (dp == NULLDCT) if (ST_level == 0) return (RP_DONE); else if ((dp = UM_pop()) == NULLDCT) return (RP_DONE); if (UM_isdir (dp->d_name)) { /* new subdir */ UM_push (dp->d_name); return (UM_rfile (buf)); } if (isstr (ST_name)) (void) sprintf (buf, "%s/%s", ST_name, dp->d_name); else (void) strcpy (buf, dp->d_name); return (RP_OK); } /* ----------------------------------------------------------------- */ static struct dirent *UM_pop() { struct dirent *dp; char tbuf[LINESIZE], *ptr; --ST_level; ptr = rindex (ST_name, '/'); (void) strcpy (tbuf, ++ptr); *--ptr = '\0'; PP_DBG (("mu: UM_pop: (%s, %d)", ST_name, ST_level)); closedir (ST_dir); ST_dir = opendir (ST_name); dp = UM_readdir (&tbuf[0]); if (dp) return (dp); if (ST_level) return (UM_pop()); return (NULLDCT); } /* ----------------------------------------------------------------- */ static UM_push (name) char *name; { char tbuf[LINESIZE]; (void) sprintf (tbuf, "%s/%s", ST_name, name); (void) strcpy (ST_name, tbuf); closedir (ST_dir); PP_DBG (("mu: UM_push: (%s, %d)", ST_name, ST_level+1)); if ((ST_dir = opendir (ST_name)) == NULLDIR) { PP_LOG (LLOG_FATAL,("mu: UM_push: Unable to open %s", ST_name)); return; } ++ST_level; } /* ----------------------------------------------------------------- */ static UM_isdir (name) char *name; { struct stat st_rec; char tbuf[LINESIZE]; if (!isstr (name)) return (FALSE); (void) strcpy (&tbuf[0], ST_name); if (strcmp (ST_name, name) != 0) { (void) strcat (&tbuf[0], "/"); (void) strcat (&tbuf[0], name); } fprintf(muout,"mu/UM_isdir testing %s as %s\n",name,tbuf); if (stat (&tbuf[0], &st_rec) == NOTOK) { PP_LOG (LLOG_FATAL, ("mu: UM_isdir: Unable to stat %s %d",&tbuf[0], errno)); return (FALSE); } switch (st_rec.st_mode & S_IFMT) { case S_IFDIR: PP_DBG (("mu/: UM_isdir (%s = TRUE)", &tbuf[0])); return (TRUE); default: PP_DBG (("mu: UM_isdir (%s = FALSE)", &tbuf[0])); return (FALSE); } } /* ----------------------------------------------------------------- */ static struct dirent *UM_readdir (current) char *current; { struct dirent *dp; int passed_current = FALSE; if (current) PP_DBG (("mu: UM_readdir (current = %s)", current)); for (dp=readdir(ST_dir); dp != NULLDCT; dp=readdir(ST_dir)) { if (strcmp (dp->d_name, ".") == 0) continue; if (strcmp (dp->d_name, "..") == 0) continue; if (current) if (strcmp (dp->d_name, current) == 0) { passed_current = TRUE; continue; } else if (passed_current == FALSE) continue; break; } if (dp) PP_DBG (("mu: UM_readdir (%s)", dp->d_name)); return (dp); } /* ----------------------------------------------------------------- */ static UM_array_free () { int i; for (i=0; i < ST_no; i++) if (ST_array[i]) { free (ST_array [i]); ST_array[i] = NULLCP; } ST_no = NULL; ST_curr = NULL; } /* ***************** End routines taken from ut_msg ******************* */ /* ----------------------------------------------------------------- */ strip(x) /* strip trailing spaces and tabs */ char *x; { int i = strlen(x); char *p; PP_DBG (("mu: strip trailing spaces & tabs from <%s>", x)); if ( i ) { p = &x[ i - 1 ]; while ( i && (*p == ' ' || *p == '\t') ) { *p-- = '\0'; i--; } } } /* ----------------------------------------------------------------- */ dump_args(argc, argv) int argc; char **argv; { int i = 0; int j = argc; fprintf(muout,"dump_args argc %d\n",argc); PP_LOG (LLOG_TRACE,("dump_args argc %d",argc)); while (j && (argv[i] != NULLCP)) { fprintf(muout,"dump_args argv[%d] %s\n",i,argv[i]); PP_LOG (LLOG_TRACE,("dump_args argv[%d] %s",i,argv[i])); j--; i++; } }