X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=parser.c;h=4b55743c1791d99a2ffab60f8bda6e43e662b5d1;hp=e173e3a1c1471bf024c78d5040ffa01515ec2056;hb=5043c988440a119e4f773c967be19a829582b8ba;hpb=703b99b834625829d6b285e5bca619475ef54511 diff --git a/parser.c b/parser.c index e173e3a..4b55743 100644 --- a/parser.c +++ b/parser.c @@ -22,28 +22,19 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -struct parser_state { - int lineno, atnewline, notedreferer; - const char *filename; - YY_BUFFER_STATE ybuf; - struct parser_state *upstate; -}; - -static const char *currentfile= 0; -static struct parser_state *parser_topstate= 0; - -static directive_fnt *lr_dir=0; -static parmcondition_fnt *lr_parmcond=0; -static parameter_fnt *lr_parameter=0; -static int lr_loglevel, lr_logfacility, lr_min, lr_max, *lr_flag; -static int lr_flagval, lr_controlend; -static int lr_fdwant_readwrite; - static void useless(void) { (void)yyunput; (void)useless; /* to shut up GCC ! */ } static void closeerrorfile(void) { - if (ehfile && !ehfilekeep) { fclose(ehfile); free(ehfilename); } - ehfile= 0; ehfilename= 0; ehfilekeep= 0; + if (eh.file && !eh.filekeep) { + if (fclose(eh.file)) { + eh.handling= tokv_word_errorstostderr; + parseerrprint("error writing to error log file `%s': %s", + eh.filename,strerror(errno)); + } + free(eh.filename); + } + eh.handling= 0; + eh.file= 0; eh.filename= 0; eh.filekeep= 0; } static void senderrmsg(const char *errmsg, int useehandling) { @@ -57,24 +48,24 @@ static void senderrmsg(const char *errmsg, int useehandling) { senderrmsgstderr(errmsg); break; case tokv_word_errorstosyslog: - ensurelogopen(ehlogfacility); - syslog(ehloglevel,"%s",errmsg); + ensurelogopen(eh.logfacility); + syslog(eh.loglevel,"%s",errmsg); break; case tokv_word_errorstofile: if (time(&now)==-1) syscallerror("get current time"); lt= localtime(&now); if (!lt) syscallerror("convert current time"); - if (fprintf(ehfile,"%d-%02d-%02d %02d:%02d:%02d: uservd: %s\n", + if (fprintf(eh.file,"%d-%02d-%02d %02d:%02d:%02d: uservd: %s\n", lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, errmsg) == EOF) { e= errno; - closeerrorfile(); ehandling= tokv_word_errorstofile; + closeerrorfile(); eh.handling= tokv_word_errorstofile; snyprintf(suberrmsg,sizeof(suberrmsg), "error writing to error log file `%.*s': %s;" " reverting to errors-to-stderr", - (int)(sizeof(suberrmsg)>>1),ehfilename,strerror(e)); - senderrmsg(suberrmsg,ehandling); - senderrmsg(errmsg,ehandling); + (int)(sizeof(suberrmsg)>>1),eh.filename,strerror(e)); + senderrmsg(suberrmsg,eh.handling); + senderrmsg(errmsg,eh.handling); } break; default: @@ -82,22 +73,22 @@ static void senderrmsg(const char *errmsg, int useehandling) { } } -static void errwhere(int iflineno, const char *filename, int *ifnotedreferer, - struct parser_state *upstate, char *bufput, int bufputlen) { +static void errwhere(struct parser_state *tstate, char *bufput, int bufputlen) { static const char suffix[]= "references ..."; char errmsg[MAX_ERRMSG_LEN]; - if (!upstate) { - filename= ""; - } else if (!*ifnotedreferer && upstate->upstate && upstate->upstate->upstate) { - errwhere(upstate->lineno-upstate->atnewline,upstate->filename, - &upstate->notedreferer,upstate->upstate, - errmsg,sizeof(errmsg)-sizeof(suffix)); + if (!tstate) { + strnycpy(bufput,": ",bufputlen); + return; + } + if (!tstate->notedreferer && tstate->upstate && !tstate->upstate->isinternal) { + errwhere(tstate->upstate,errmsg,sizeof(errmsg)-sizeof(suffix)); strcat(errmsg,suffix); - senderrmsg(errmsg,ehandling); - *ifnotedreferer= 1; + senderrmsg(errmsg,eh.handling); + tstate->notedreferer= 1; } - snyprintf(bufput,bufputlen,"%.*s:%d: ",bufputlen-10,filename,iflineno); + snyprintf(bufput,bufputlen,"%.*s:%d: ",bufputlen-10, + tstate->filename,tstate->reportlineno); } void parseerrprint(const char *fmt, ...) { @@ -105,10 +96,9 @@ void parseerrprint(const char *fmt, ...) { char errmsg[MAX_ERRMSG_LEN]; va_start(al,fmt); - errwhere(lineno-atnewline,currentfile,¬edreferer,parser_topstate, - errmsg,sizeof(errmsg)>>1); + errwhere(cstate,errmsg,sizeof(errmsg)>>1); vsnytprintfcat(errmsg,sizeof(errmsg),fmt,al); - senderrmsg(errmsg,ehandling); + senderrmsg(errmsg,eh.handling); va_end(al); } @@ -209,44 +199,35 @@ static const char *string2path(const char *in) { static char *p=0; static int pl=0; - int l; - - if (strncmp(in,USERDIRPREFIX,sizeof(USERDIRPREFIX)-1)) return in; - l= strlen(serviceuser_dir)+strlen(in)+1-(sizeof(USERDIRPREFIX)-1)+ - sizeof(DIRSEP)-1; - if (l>pl) { p= realloc(p,l); pl=l; } - strcpy(p,serviceuser_dir); strcat(p,DIRSEP); - strcat(p,in+(sizeof(USERDIRPREFIX)-1)); + if (strncmp(in,"~/",2)) return in; + makeroom(&p,&pl,strlen(serviceuser_dir)+1+strlen(in+2)+1); + snyprintf(p,pl,"%s/%s",serviceuser_dir,in+2); return p; } -static void parser_push(struct parser_state *saveinto, - const char *newfile) { - saveinto->lineno= lineno; - saveinto->atnewline= atnewline; - saveinto->filename= currentfile; - saveinto->notedreferer= notedreferer; - saveinto->ybuf= YY_CURRENT_BUFFER; - saveinto->upstate= parser_topstate; - - lineno= 1; - notedreferer= 0; - currentfile= newfile; - parser_topstate= saveinto; +static void parser_push(struct parser_state *usestate, + const char *newfile, + YY_BUFFER_STATE ybuf, + int isinternal) { + usestate->lineno= 1; + usestate->reportlineno= 1; + usestate->filename= newfile; + usestate->notedreferer= 0; + usestate->isinternal= isinternal; + usestate->ybuf= ybuf; + usestate->upstate= cstate; + + cstate= usestate; + yy_switch_to_buffer(ybuf); } static void parser_pop(void) { - YY_BUFFER_STATE ybuf; - ybuf= YY_CURRENT_BUFFER; - - lineno= parser_topstate->lineno; - atnewline= parser_topstate->atnewline; - currentfile= parser_topstate->filename; - notedreferer= parser_topstate->notedreferer; - if (parser_topstate->ybuf) yy_switch_to_buffer(parser_topstate->ybuf); - parser_topstate= parser_topstate->upstate; - - yy_delete_buffer(ybuf); + struct parser_state *oldstate; + + oldstate= cstate; + cstate= cstate->upstate; + if (cstate) yy_switch_to_buffer(cstate->ybuf); + yy_delete_buffer(oldstate->ybuf); } /* parser component functions pa_ return tokv_error or 0, @@ -276,7 +257,7 @@ static int pa_mwsp(void) { static void parm_1string(char ***rvalues, const char *tocopy) { char **a; a= xmalloc(sizeof(char*)*2); - a[0]= xstrdup(tocopy); + a[0]= xstrsave(tocopy); a[1]= 0; *rvalues= a; } @@ -315,30 +296,39 @@ static int paa_1path(const char **rv) { *rv= string2path(cp); return 0; } -static int pa_parameter(char ***rvalues) { +static int pa_parameter(char ***rvalues, char **rname) { /* Scans a single parameter token and calls the appropriate parameter * function, returning tokv_error or 0 just like the parameter function. + * If rname is non-null then the name of the parameter (malloc'd) will + * be stored in it. */ int token, r, i; + char *name; token= yylex(); if (token == tokv_error) return token; + name= xstrsave(yytext); if ((token & tokm_repres) != tokr_nonstring && !memcmp(yytext,"u-",2) && strlen(yytext)>=3) { for (i=0; - i=request_mbuf.nvars) { *rvalues= xmalloc(sizeof(char*)); **rvalues= 0; } else { - parm_1string(rvalues,defvararray[i][1]); + parm_1string(rvalues,defvararray[i].value); } } else { - if (!(token & tokt_parameter)) return unexpected(token,-1,"parameter name"); + if (!(token & tokt_parameter)) { + free(name); + return unexpected(token,-1,"parameter name"); + } r= (lr_parameter)(token,rvalues); - if (r) return r; + if (r) { free(name); return r; } } - debug_dumpparameter(yytext,*rvalues); + debug_dumpparameter(name,*rvalues); + if (rname) *rname= name; + else free(name); return 0; } @@ -361,6 +351,7 @@ static int pa_condition(int *rtrue) { } else if (token == tokv_openparen) { andor= 0; actrue= -1; for (;;) { + cstate->reportlineno= cstate->lineno; r= pa_condition(&ctrue); if (r) return r; switch (andor) { case 0: assert(actrue==-1); actrue= ctrue; break; @@ -383,7 +374,7 @@ static int pa_condition(int *rtrue) { *rtrue= actrue; return 0; } else if (token & tokt_parmcondition) { r= pa_mwsp(); if (r) return r; - r= pa_parameter(&parmvalues); if (r) return r; + r= pa_parameter(&parmvalues,0); if (r) return r; r= (lr_parmcond)(token,parmvalues,rtrue); freecharparray(parmvalues); return r; } @@ -422,6 +413,7 @@ static int skip(int allowce) { int token, r; for (;;) { /* loop over lines */ + cstate->reportlineno= cstate->lineno; do { token= yylex(); } while (token == tokv_lwsp); if (token & tokt_exception) { return token; @@ -432,6 +424,7 @@ static int skip(int allowce) { r= token; while (r & tokt_controlstart) { r= skiptoeol(); if (r) return r; + cstate->reportlineno= cstate->lineno; r= skip(token); if (r & tokt_exception) return r; } } else if (!(token & tokt_directive) && !(token & tokt_condop)) { @@ -454,6 +447,7 @@ static int parser(int allowce) { int token, r; for (;;) { /* loop over lines */ + cstate->reportlineno= cstate->lineno; do { token= yylex(); } while (token == tokv_lwsp); if (token & tokt_exception) { return token; @@ -470,17 +464,16 @@ static int parser(int allowce) { } } -int parse_string(const char *string, const char *descrip) { +int parse_string(const char *string, const char *descrip, int isinternal) { /* Returns the same things as parser, except that tokv_eof * is turned into 0. */ - struct parser_state save; + struct parser_state usestate; YY_BUFFER_STATE ybuf; int r; - - parser_push(&save,descrip); + ybuf= yy_scan_string(string); if (!ybuf) syscallerror("unable to create flex buffer for internal string"); - yy_switch_to_buffer(ybuf); + parser_push(&usestate,descrip,ybuf,isinternal); r= parser(0); @@ -494,7 +487,7 @@ static int parse_file(const char *string, int *didexist) { * is turned into 0. */ static int fileparselevel= 0; - struct parser_state save; + struct parser_state usestate; YY_BUFFER_STATE ybuf; int r; FILE *file; @@ -513,10 +506,9 @@ static int parse_file(const char *string, int *didexist) { } if (didexist) *didexist= 1; - parser_push(&save,string); ybuf= yy_create_buffer(file,YY_BUF_SIZE); if (!ybuf) syscallerror("unable to create flex buffer for file"); - yy_switch_to_buffer(ybuf); + parser_push(&usestate,string,ybuf,0); fileparselevel++; r= parser(0); @@ -635,7 +627,7 @@ static char *parm_ulong(unsigned long ul) { static int parm_usernameuid(char ***rvalues, const char *name, uid_t id) { char **a; a= xmalloc(sizeof(char*)*3); - a[0]= xstrdup(name); + a[0]= xstrsave(name); a[1]= parm_ulong(id); a[2]= 0; *rvalues= a; return 0; @@ -659,7 +651,7 @@ static char *parm_gidname(gid_t id) { sprintf(ebuf,"look up group with id %lu",(unsigned long)id); syscallerror(ebuf); } - return xstrdup(ge->gr_name); + return xstrsave(ge->gr_name); } static int parm_gids(char ***rvalues, int size, gid_t *list) { @@ -677,27 +669,15 @@ static int parm_gids(char ***rvalues, int size, gid_t *list) { } int pf_callinggroup(int ptoken, char ***rvalues) { - return parm_gids(rvalues,request_mbuf.ngids,gidarray); + return parm_gids(rvalues,request_mbuf.ngids,calling_gids); } int pf_servicegroup(int ptoken, char ***rvalues) { - static int size=-1; - static gid_t *list; - - if (size == -1) { - size= getgroups(0,0); if (size == -1) syscallerror("getgroups(0,0)"); - list= xmalloc(sizeof(gid_t)*(size+1)); - if (getgroups(size,list+1) != size) syscallerror("getgroups(size,list)"); - list[0]= serviceuser_gid; - } - return parm_gids(rvalues,size,list); + return parm_gids(rvalues,service_ngids,service_gids); } int pf_callingusershell(int ptoken, char ***rvalues) { - struct passwd *pw; - - pw= getpwnam(logname); if (!pw) syscallerror("looking up calling user"); - parm_1string(rvalues,pw->pw_shell); return 0; + parm_1string(rvalues,callinguser_shell); return 0; } int pf_serviceusershell(int ptoken, char ***rvalues) { @@ -706,26 +686,6 @@ int pf_serviceusershell(int ptoken, char ***rvalues) { /* Directive functions and associated `common code' functions */ -int df_reject(int dtoken) { - int r; - - r= pa_mnl(); if (r) return r; - execute= tokv_word_reject; - free(execpath); execpath= 0; - freecharparray(execargs); execargs= 0; - return 0; -} - -int df_executefrompath(int dtoken) { - int r; - - r= pa_mnl(); if (r) return r; - execute= tokv_word_executefrompath; - free(execpath); execpath= 0; - freecharparray(execargs); execargs= 0; - return 0; -} - static int paa_pathargs(const char **rv, char ***newargs_r) { /* Repeated calls do _not_ overwrite newargs_r; caller must free. * Repeated calls _do_ overwrite string returned in rv. @@ -752,7 +712,7 @@ static int paa_pathargs(const char **rv, char ***newargs_r) { size= (used+5)<<2; newargs= xrealloc(newargs,sizeof(char*)*(size+1)); } - newargs[used++]= xmstrsave(yytext); + newargs[used++]= xstrsave(yytext); } newargs[used]= 0; *newargs_r= newargs; @@ -764,15 +724,41 @@ error: return r; } +static void execreset(void) { + execute= 0; + execbuiltin= 0; + free(execpath); execpath= 0; + freecharparray(execargs); execargs= 0; +} + +int df_reject(int dtoken) { + int r; + + r= pa_mnl(); if (r) return r; + execreset(); + execute= tokv_word_reject; + return 0; +} + +int df_executefrompath(int dtoken) { + int r; + + r= pa_mnl(); if (r) return r; + execreset(); + execute= tokv_word_executefrompath; + return 0; +} + int df_execute(int dtoken) { const char *rv; char **newargs; int r; r= paa_pathargs(&rv,&newargs); if (r) return r; + execreset(); execute= tokv_word_execute; - freecharparray(execargs); execargs= newargs; - free(execpath); execpath= xmstrsave(rv); + execargs= newargs; + execpath= xstrsave(rv); return 0; } @@ -800,8 +786,9 @@ int df_executefromdirectory(int dtoken) { return tokv_error; } } - l= strlen(rv)+sizeof(DIRSEP)+strlen(p); - fn= xmalloc(l); strcpy(fn,rv); strcat(fn,DIRSEP); strcat(fn,p); + l= strlen(rv)+1+strlen(p)+1; + fn= xmalloc(l); + snyprintf(fn,l,"%s/%s",rv,p); if (stat(fn,&stab)) { if (errno == ENOENT) { free(fn); freecharparray(newargs); return 0; } parseerrprint("failed to stat `%s' for execute-from-directory: %s", @@ -813,9 +800,51 @@ int df_executefromdirectory(int dtoken) { " or link to one (mode=0%o)",fn,stab.st_mode); free(fn); freecharparray(newargs); return tokv_error; } + execreset(); execute= tokv_word_executefromdirectory; - freecharparray(execargs); execargs= newargs; - free(execpath); execpath= fn; + execargs= newargs; + execpath= fn; + return 0; +} + +static int bispa_none(char ***rnewargs) { + return pa_mnl(); +} + +static int bispa_parameter(char ***rnewargs) { + int r, i; + char **parmvalues, *name, **newargs; + + r= pa_mwsp(); if (r) return r; + r= pa_parameter(&parmvalues,&name); if (r) return r; + for (i=0; parmvalues[i]; i++); + newargs= xmalloc(sizeof(char*)*(i+2)); + newargs[0]= name; + memcpy(newargs+1,parmvalues,sizeof(char*)*(i+1)); + free(parmvalues); + r= pa_mnl(); if (r) { free(newargs); return r; } + *rnewargs= newargs; + return 0; +} + +int df_executebuiltin(int dtoken) { + int r; + builtinserviceexec_fnt *bisexec; + char *newpath, **newargs; + + r= pa_mwsp(); if (r) return r; + r= yylex(); if (r == tokv_error) return r; + if (!(r & tokt_builtinservice)) return unexpected(r,-1,"builtin service name"); + bisexec= lr_bisexec; + newpath= xstrsave(yytext); + newargs= 0; + r= lr_bispa(&newargs); if (r) { free(newpath); return r; } + + execreset(); + execute= tokv_word_executebuiltin; + execbuiltin= bisexec; + execpath= newpath; + execargs= newargs; return 0; } @@ -823,7 +852,7 @@ int df_errorstostderr(int dtoken) { int r; r= pa_mnl(); if (r) return r; - closeerrorfile(); ehandling= dtoken; return 0; + closeerrorfile(); eh.handling= dtoken; return 0; } int df_errorstosyslog(int dtoken) { @@ -848,8 +877,8 @@ int df_errorstosyslog(int dtoken) { } if (unexpected(token,tokv_newline,"end of line somewhere after errors-to-syslog")) return tokv_error; - closeerrorfile(); ehandling= tokv_word_errorstosyslog; - ehlogfacility= facility; ehloglevel= level; return 0; + closeerrorfile(); eh.handling= tokv_word_errorstosyslog; + eh.logfacility= facility; eh.loglevel= level; return 0; } int df_errorstofile(int dtoken) { @@ -867,8 +896,8 @@ int df_errorstofile(int dtoken) { parseerrprint("unable to set line buffering on errors file: %s",strerror(errno)); fclose(file); return tokv_error; } - closeerrorfile(); ehandling= tokv_word_errorstofile; - ehfile= file; ehfilename= xmstrsave(cp); ehfilekeep= 0; return 0; + closeerrorfile(); eh.handling= tokv_word_errorstofile; + eh.file= file; eh.filename= xstrsave(cp); return 0; } int dfg_setflag(int dtoken) { @@ -882,7 +911,7 @@ int df_reset(int dtoken) { int r; r= pa_mnl(); if (r) return r; - r= parse_string(RESET_CONFIGURATION,""); + r= parse_string(RESET_CONFIGURATION,"",1); assert(!r); return 0; } @@ -901,7 +930,7 @@ int df_userrcfile(int dtoken) { int r; r= paa_1path(&cp); if (r) return r; - free(userrcfile); userrcfile= xstrdup(cp); + free(userrcfile); userrcfile= xstrsave(cp); return 0; } @@ -923,7 +952,7 @@ int dfi_includeclientconfig(int dtoken) { "found but configuration not overridden"); return tokv_error; } - return parse_string(overridedata,""); + return parse_string(overridedata,"",0); } int df_include(int dtoken) { @@ -1004,10 +1033,8 @@ int df_includedirectory(int dtoken) { if (!isalnum(*p)) continue; while ((c= *++p)) if (!(isalnum(c) || c=='-')) break; if (c) continue; - makeroom(&buildbuf,&buildbuflen,cpl+tel+sizeof(DIRSEP)); - strcpy(buildbuf,cp); - strcat(buildbuf,DIRSEP); - strcat(buildbuf,de->d_name); + makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1); + snyprintf(buildbuf,buildbuflen,"%s/%s",cp,de->d_name); r= parse_file(buildbuf,&found); if (r) { closedir(d); return r; } if (!found) { parseerrprint("unable to open file `%s' in included directory `%s': %s", @@ -1032,7 +1059,7 @@ int df_includelookup(int dtoken) { int r, done, thisdone, cpl, c; r= pa_mwsp(); if (r) return r; - r= pa_parameter(&parmvalues); if (r) return r; + r= pa_parameter(&parmvalues,0); if (r) return r; r= paa_1path(&cp); if (r) { freecharparray(parmvalues); return r; } if (stat(cp,&stab)) { parseerrprint("unable to access directory `%s': %s",cp,strerror(errno)); @@ -1045,9 +1072,8 @@ int df_includelookup(int dtoken) { done= 0; cpl= strlen(cp); if (!parmvalues[0]) { - makeroom(&buildbuf,&buildbuflen,cpl+sizeof(DIRSEP NONEINCLUDELOOKUP)); - strcpy(buildbuf,cp); - strcat(buildbuf,DIRSEP NONEINCLUDELOOKUP); + makeroom(&buildbuf,&buildbuflen,cpl+1+sizeof(NONEINCLUDELOOKUP)); + snyprintf(buildbuf,buildbuflen,"%s/" NONEINCLUDELOOKUP,cp); r= parse_file(buildbuf,&thisdone); if (r) { freecharparray(parmvalues); return r; } if (thisdone) done= 1; @@ -1056,10 +1082,10 @@ int df_includelookup(int dtoken) { *pp && (!done || dtoken == tokv_word_includelookupall); pp++) { makeroom(&buildbuf,&buildbuflen, - cpl+sizeof(DIRSEP)+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)); + cpl+1+strlen(*pp)*2+3+sizeof(EMPTYINCLUDELOOKUP)+1); strcpy(buildbuf,cp); - strcat(buildbuf,DIRSEP); - p= *pp; q= buildbuf+cpl+sizeof(DIRSEP)-1; + p= *pp; q= buildbuf+cpl; + *q++= '/'; if (*p=='.') *q++= ':'; while ((c= *p++)) { if (c=='/') { *q++= ':'; c='-'; } @@ -1075,9 +1101,8 @@ int df_includelookup(int dtoken) { freecharparray(parmvalues); if (!done) { makeroom(&buildbuf,&buildbuflen, - cpl+sizeof(DIRSEP)+sizeof(DEFAULTINCLUDELOOKUP)); - strcpy(buildbuf,cp); - strcat(buildbuf,DIRSEP DEFAULTINCLUDELOOKUP); + cpl+1+sizeof(DEFAULTINCLUDELOOKUP)); + snyprintf(buildbuf,buildbuflen,"%s/" DEFAULTINCLUDELOOKUP,cp); r= parse_file(buildbuf,0); if (r) return r; } return 0; @@ -1094,11 +1119,8 @@ int df_catchquit(int dtoken) { } else if (r == tokv_quit || r == tokv_error) { if (r == tokv_error) { r= parse_string(RESET_CONFIGURATION, - ""); + "",1); assert(!r); - while (!atnewline) { - r= yylex(); if (r == tokv_error) return r; - } } r= skip(tokv_word_catchquit); if (r & tokt_controlend) { @@ -1121,6 +1143,7 @@ int df_if(int dtoken) { } while (r == tokv_word_elif); if (r == tokv_word_else) { r= pa_mnl(); if (r) return r; + cstate->reportlineno= cstate->lineno; if (done) r= skip(tokv_word_if); else r= parser(tokv_word_if); if (!(r & tokv_word_if)) return r; @@ -1185,29 +1208,18 @@ int df_eof(int dtoken) { } int df_errorspush(int dt) { - int saveehandling, saveehlogfacility, saveehloglevel, saveehfilekeep; - FILE *saveehfile; - char *saveehfilename; + struct error_handling save; int r; r= pa_mnl(); if (r) return r; - saveehandling= ehandling; - saveehlogfacility= ehlogfacility; - saveehloglevel= ehloglevel; - saveehfile= ehfile; - saveehfilekeep= ehfilekeep; - saveehfilename= ehfilename; - if (ehandling == tokv_word_errorstofile) ehfilekeep= 1; + save= eh; + eh.filekeep= 1; r= parser(tokv_word_errorspush); - - ehandling= saveehandling; - ehlogfacility= saveehlogfacility; - ehloglevel= saveehloglevel; - ehfile= saveehfile; - ehfilekeep= saveehfilekeep; - ehfilename= saveehfilename; + + closeerrorfile(); + eh= save; if (r & tokt_controlend) { assert(r == tokv_word_srorre);