Rev 12246 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 1 | /* Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
16 | */ |
||
17 | |||
7673 | bpr | 18 | /* Low-level variable management routines. */ |
8185 | bpr | 19 | #include "wims.h" |
10 | reyssat | 20 | |
7673 | bpr | 21 | #define VARBUF_LEN (256*1024) |
22 | #define VARBUF_NUM 16 |
||
23 | #define VARNAME_LEN 32768 |
||
24 | #define VARNUM_LIMIT 4096 |
||
25 | #define vb_internal 1 |
||
26 | #define vb_ro 2 |
||
27 | #define vb_dirty 4 |
||
28 | #define vb_noexport 8 |
||
29 | #define vb_hacked 16 |
||
10 | reyssat | 30 | |
7673 | bpr | 31 | char *_varbuf[VARBUF_NUM]; /* main variable value buffer */ |
10 | reyssat | 32 | char *_varptr; |
33 | int _varbufcurr; |
||
34 | char *_varnamebuf, *_varnameptr; /* variable name buffer */ |
||
35 | |||
7673 | bpr | 36 | /* wims_ variables that should be exported */ |
10 | reyssat | 37 | char *exportvars[]={ |
38 | "class", |
||
39 | "deposit", |
||
40 | "home", |
||
41 | "inssub", |
||
42 | "sesdir", |
||
43 | "session", |
||
44 | "site_languages", |
||
45 | "supervisor", |
||
46 | "supervisormail", |
||
47 | "tmp_debug", |
||
48 | "user", |
||
49 | "version", |
||
50 | }; |
||
8185 | bpr | 51 | int exportvarcnt=(sizeof(exportvars)/sizeof(exportvars[0])); |
10 | reyssat | 52 | |
53 | struct vartab { |
||
12246 | bpr | 54 | char *name, *val; |
55 | unsigned short int vlen; |
||
56 | char tag,lvl; |
||
10 | reyssat | 57 | } fastvartab[128], mainvartab[VARNUM_LIMIT]; |
58 | |||
7673 | bpr | 59 | /* int vlenmin[]={0,1,20,45,100,200,400,800,1500,3000,6000}; */ |
13573 | obado | 60 | int vlenmax[]={1,32,64,128,256,512,1024,2048,4096,8192,MAX_LINELEN+1}; |
61 | int freelim[]={1,500,500,300,200,150,100,80,60,50,30}; |
||
10 | reyssat | 62 | #define lvlno (sizeof(vlenmax)/sizeof(vlenmax[0])) |
13573 | obado | 63 | #define freevtot (1+500+500+300+200+150+100+80+60+50+30) |
10 | reyssat | 64 | |
65 | int freevars[lvlno], freevstart[lvlno]; |
||
66 | int freevcnt=0,bufvcnt=0; |
||
67 | char *freevbuf[freevtot]; |
||
68 | int mainvarcnt=0; |
||
69 | void add_hack(char *name); |
||
70 | |||
71 | void get_var_privileges(void) |
||
72 | { |
||
12246 | bpr | 73 | int sav=untrust; |
74 | untrust=0; |
||
75 | var_readable=getvar("wims_readable"); |
||
76 | var_writable=getvar("wims_writable"); |
||
77 | var_nr=getvar("wims_nr"); |
||
78 | var_nw=getvar("wims_nw"); |
||
79 | var_pfx=getvar("wims_prefix"); |
||
80 | untrust=sav; |
||
10 | reyssat | 81 | } |
82 | |||
7673 | bpr | 83 | /* Returns 1 if rights OK. Else 0. */ |
10 | reyssat | 84 | int var_checkright(char *name, char *allow, char *deny, char *prefix) |
85 | { |
||
12246 | bpr | 86 | if(strcmp(name,"wims_read_parm")==0) return 1; |
87 | if(allow!=NULL && allow[0]!=0 && wordchr(allow,name)!=NULL) return 1; |
||
88 | if(deny!=NULL && deny[0]!=0 && wordchr(deny,name)!=NULL) return 0; |
||
89 | if(prefix!=NULL && prefix[0]!=0) { |
||
90 | char *p, buf[MAX_NAMELEN+1]; |
||
91 | for(p=name; *p!=0 && *p!='_'; p++); |
||
92 | if(*p!='_' || p-name>=MAX_NAMELEN) return 0; |
||
93 | memmove(buf,name,p-name); buf[p-name]=0; |
||
94 | if(wordchr(prefix,buf)==NULL) return 0; |
||
95 | } |
||
96 | return 1; |
||
10 | reyssat | 97 | } |
98 | |||
7673 | bpr | 99 | /* initialisation */ |
10 | reyssat | 100 | void var_init(void) |
101 | { |
||
12246 | bpr | 102 | int i,j; |
103 | memset(freevars,0,sizeof(freevars)); |
||
104 | _varbufcurr=0; |
||
105 | _varbuf[0]=xmalloc(VARBUF_LEN); |
||
106 | _varnamebuf=xmalloc(VARNAME_LEN); |
||
107 | _varptr=_varbuf[0]; _varnameptr=_varnamebuf; |
||
108 | for(i=j=0;i<lvlno;i++) {freevstart[i]=j; j+=freelim[i];} |
||
109 | if(j!=freevtot) internal_error("var.c: wrong count freevtot!"); |
||
10 | reyssat | 110 | } |
111 | |||
112 | void exportall(void) |
||
113 | { |
||
12246 | bpr | 114 | int i, j, tag; char buf[MAX_NAMELEN+17]; |
115 | char *p, *p1, *p2; |
||
116 | char *noexpword[1024]; |
||
117 | int noexplen[1024]; |
||
118 | int noexpcnt; |
||
7673 | bpr | 119 | |
12246 | bpr | 120 | noexpcnt=0; |
121 | p=getvar("wims_noexport"); if(p==NULL) p=""; |
||
122 | for(p1=find_word_start(p),noexpcnt=0; |
||
123 | *p1 && noexpcnt<1024; |
||
124 | p1=find_word_start(p2)) { |
||
125 | p2=find_word_end(p1); |
||
126 | noexpword[noexpcnt]=p1; noexplen[noexpcnt]=p2-p1; |
||
127 | noexpcnt++; |
||
128 | } |
||
129 | for(i=0;i<mainvarcnt;i++) { |
||
130 | tag=mainvartab[i].tag; |
||
131 | if((tag&vb_dirty)==0 || (tag&vb_noexport)!=0) continue; |
||
132 | p=mainvartab[i].name; |
||
133 | for(j=0;j<noexpcnt;j++) if(strncmp(p,noexpword[j],noexplen[j])==0) { |
||
134 | mainvartab[i].tag|=vb_noexport; |
||
135 | goto lend; |
||
10 | reyssat | 136 | } |
12246 | bpr | 137 | if(mainvartab[i].tag&vb_hacked) { |
138 | add_hack(p); mainvartab[i].tag&=~vb_hacked; |
||
10 | reyssat | 139 | } |
12246 | bpr | 140 | snprintf(buf,sizeof(buf),"%s%s",var_prefix,p); |
141 | setenv(buf,mainvartab[i].val,1); |
||
142 | mainvartab[i].tag&=~vb_dirty; |
||
143 | lend: ; |
||
144 | } |
||
10 | reyssat | 145 | } |
146 | |||
147 | char *vaskbuf(int lvl) |
||
148 | { |
||
12246 | bpr | 149 | char *p; |
150 | if(lvl>=lvlno) { /* should never occur */ |
||
151 | module_error("Internal_variable_length_overflow"); return NULL; |
||
152 | } |
||
153 | if(freevars[lvl]>0) { |
||
154 | freevars[lvl]--; freevcnt--; |
||
155 | return freevbuf[freevstart[lvl]+freevars[lvl]]; |
||
156 | } |
||
157 | if(_varptr+vlenmax[lvl]>=_varbuf[_varbufcurr]+VARBUF_LEN) { |
||
158 | if(_varbufcurr>=VARBUF_NUM) { |
||
159 | module_error("variable_buffer_overflow"); return NULL; |
||
10 | reyssat | 160 | } |
12246 | bpr | 161 | _varbufcurr++; _varptr=_varbuf[_varbufcurr]=xmalloc(VARBUF_LEN); |
162 | } |
||
163 | bufvcnt++; |
||
164 | p=_varptr; _varptr+=vlenmax[lvl]; return p; |
||
10 | reyssat | 165 | } |
166 | |||
7673 | bpr | 167 | /* returns 1 if free succeeded. */ |
10 | reyssat | 168 | int vfreebuf(int lvl, char *p) |
169 | { |
||
12246 | bpr | 170 | if(p>=_varptr) return 0; |
171 | if(p+vlenmax[lvl]==_varptr) {_varptr=p; bufvcnt--;return 1;} |
||
172 | if(lvl<=0 || lvl>=lvlno || freevars[lvl]>=freelim[lvl]) return 0; |
||
173 | freevcnt++; |
||
174 | freevbuf[freevstart[lvl]+freevars[lvl]]=p; freevars[lvl]++; return 1; |
||
10 | reyssat | 175 | } |
176 | |||
177 | int _char_int(char *vn) |
||
178 | { |
||
12246 | bpr | 179 | int t; char v; |
180 | v=vn[0]; if(vn[1]) t=64; else t=0; |
||
181 | if(v>='0' && v<='9') return v-'0'+t; |
||
182 | else { |
||
183 | if(v>='A' && v<='Z') return v-'A'+10+t; |
||
10 | reyssat | 184 | else { |
12246 | bpr | 185 | if(v>='a' && v<='z') return v-'a'+10+26+t; |
186 | else return -1; |
||
10 | reyssat | 187 | } |
12246 | bpr | 188 | } |
10 | reyssat | 189 | } |
190 | |||
191 | int var_ins(char *name,int inspoint) |
||
192 | { |
||
12246 | bpr | 193 | int i, nlen, tag; |
194 | if(mainvarcnt>=VARNUM_LIMIT) { |
||
195 | module_error("too_many_variable_names"); return -1; |
||
196 | } |
||
197 | for(nlen=0;nlen<=MAX_NAMELEN && (myisalnum(name[nlen]) || name[nlen]=='_');nlen++); |
||
198 | if(nlen<=1 || nlen>MAX_NAMELEN || name[nlen]!=0) return -1; |
||
199 | if(_varnameptr+nlen+1>_varnamebuf+VARNAME_LEN) { |
||
200 | module_error("variable_name_buffer_overflow"); return -1; |
||
201 | } |
||
202 | tag=0; |
||
203 | if(search_list(ro_name,RO_NAME_NO,sizeof(ro_name[0]),name)>=0) |
||
204 | tag|=vb_ro; |
||
205 | if(nlen<=2 || strncmp(name,mathfont_prefix,strlen(mathfont_prefix))==0 || |
||
206 | name[nlen-1]=='_') |
||
207 | tag|=vb_noexport; |
||
208 | if(var_noexport) tag|=vb_noexport; |
||
209 | if(name[0]=='w' && strncmp(name,wims_prefix,wpflen)==0) { |
||
210 | if(search_list(exportvars,exportvarcnt,sizeof(exportvars[0]),name+wpflen)<0) |
||
10 | reyssat | 211 | tag|=vb_noexport; |
12246 | bpr | 212 | if(strncmp(name+wpflen,"priv_",strlen("priv_"))==0 || |
7673 | bpr | 213 | search_list(internal_name,INTERNAL_NAME_NO,sizeof(internal_name[0]),name+wpflen)>=0) |
12246 | bpr | 214 | tag|=vb_internal; |
215 | } |
||
216 | i=inspoint; if(i>mainvarcnt) i=mainvarcnt; if(i<0) i=0; |
||
217 | memmove(mainvartab+i+1,mainvartab+i,(mainvarcnt-i)*sizeof(mainvartab[0])); |
||
218 | mainvarcnt++; nlen++; |
||
219 | memmove(_varnameptr,name,nlen); |
||
220 | mainvartab[i].name=_varnameptr; _varnameptr+=nlen; |
||
221 | mainvartab[i].val=NULL; mainvartab[i].vlen=0; |
||
222 | mainvartab[i].tag=tag; |
||
223 | mainvartab[i].lvl=0; return i; |
||
10 | reyssat | 224 | } |
225 | |||
226 | char *fast_getvar(char *vname) |
||
227 | { |
||
12246 | bpr | 228 | int n; |
10 | reyssat | 229 | |
12246 | bpr | 230 | n=_char_int(vname); if(n<0) return ""; |
231 | if(fastvartab[n].tag&vb_hacked) { |
||
232 | add_hack(vname); fastvartab[n].tag&=~vb_hacked; |
||
233 | } |
||
234 | getvar_len=fastvartab[n].vlen; |
||
235 | return fastvartab[n].val; |
||
10 | reyssat | 236 | } |
237 | |||
238 | int _setvar_(struct vartab *vtb, char *vval) |
||
239 | { |
||
12246 | bpr | 240 | int l,lvl; |
241 | char *p; |
||
242 | if(vval) l=strlen(vval); else l=0; |
||
243 | if(l>MAX_LINELEN) return 1; |
||
244 | lvl=vtb->lvl; |
||
245 | if(l==0) { |
||
246 | if(lvl>0) { |
||
247 | vfreebuf(lvl,vtb->val); vtb->tag|=vb_dirty; |
||
248 | if(var_hacking) vtb->tag|=vb_hacked; else vtb->tag&=~vb_hacked; |
||
249 | vtb->lvl=0; vtb->vlen=0; |
||
10 | reyssat | 250 | } |
12246 | bpr | 251 | if(vval) vtb->val=""; else vtb->val=NULL; |
252 | return 0; |
||
253 | } |
||
254 | if(l>=vlenmax[lvl]) { |
||
255 | vfreebuf(lvl,vtb->val); |
||
256 | do lvl++; while(l>=vlenmax[lvl]); |
||
257 | vtb->lvl=lvl; |
||
258 | vtb->val=p=vaskbuf(lvl); |
||
10 | reyssat | 259 | } |
12246 | bpr | 260 | else p=vtb->val; |
261 | vtb->vlen=l; vtb->tag|=vb_dirty; |
||
262 | if(var_hacking) vtb->tag|=vb_hacked; else vtb->tag&=~vb_hacked; |
||
263 | memmove(p,vval,++l); return 0; |
||
10 | reyssat | 264 | } |
265 | |||
266 | int fast_setvar(char *vname, char *vval) |
||
267 | { |
||
12246 | bpr | 268 | int n; |
7673 | bpr | 269 | |
12246 | bpr | 270 | n=_char_int(vname); if(n<0) return 1; |
271 | return _setvar_(fastvartab+n,vval); |
||
10 | reyssat | 272 | } |
273 | |||
7673 | bpr | 274 | /* internal constant */ |
10 | reyssat | 275 | int setvar_force=0; |
276 | |||
7673 | bpr | 277 | /* Set a user variable. Now it no longer uses environment. |
278 | * Returns 0 if OK. */ |
||
10 | reyssat | 279 | int setvar(char *vname, char *vvalue) |
280 | { |
||
12246 | bpr | 281 | int i,overwrite,tag; |
7673 | bpr | 282 | |
12246 | bpr | 283 | if(vname[0]==0) return 1; |
284 | if((vname[1]==0 || (vname[1]=='_' && vname[2]==0))) |
||
285 | return fast_setvar(vname,vvalue); |
||
286 | i=search_list(mainvartab,mainvarcnt,sizeof(mainvartab[0]),vname); |
||
287 | if(i<0) i=var_ins(vname,~i); |
||
288 | if(i<0) return 1; /* error */ |
||
289 | overwrite=1; tag=mainvartab[i].tag; |
||
290 | if(setvar_force==0 && confset==0) { |
||
7673 | bpr | 291 | /* user file has no right to modify wims variables. */ |
12246 | bpr | 292 | if((untrust&6)!=0) { |
293 | if(var_checkright(vname,var_writable,var_nw,var_pfx)==0) |
||
294 | return 1; |
||
295 | if(strncmp(vname,wims_prefix,wpflen)==0 && |
||
296 | strcmp(vname,"wims_read_parm")!=0) return 1; |
||
10 | reyssat | 297 | } |
12246 | bpr | 298 | if((tag&vb_ro)!=0) overwrite=0; |
299 | else if((tag&vb_internal)!=0 && !trusted_module()) return 1; |
||
300 | } |
||
301 | if(!overwrite && mainvartab[i].val!=NULL) return 1; |
||
302 | _setvar_(mainvartab+i,vvalue); |
||
303 | if(vname[0]=='w') { |
||
304 | if(strcmp(vname,"wims_print_precision")==0) { |
||
305 | int a=atoi(vvalue); |
||
306 | if(a>0 && a<100) print_precision=a; |
||
10 | reyssat | 307 | } |
12246 | bpr | 308 | if(strcmp(vname,"wims_backslash_insmath")==0) { |
309 | if(strcasecmp(vvalue,"yes")==0) backslash_insmath=1; |
||
310 | else backslash_insmath=0; |
||
11104 | bpr | 311 | } |
12246 | bpr | 312 | } |
313 | if (trace_file && wordchr(tmp_debug_var,vname)) { |
||
314 | fprintf(trace_file,"\n%s='%s'\n",vname,vvalue); |
||
315 | } |
||
316 | return 0; |
||
10 | reyssat | 317 | } |
318 | |||
319 | int force_setvar(char *vname,char *vvalue) |
||
320 | { |
||
12246 | bpr | 321 | int i; |
322 | setvar_force=1; i=setvar(vname,vvalue); setvar_force=0; return i; |
||
10 | reyssat | 323 | } |
324 | |||
325 | void unsetvar(char *vname) |
||
326 | { |
||
12246 | bpr | 327 | int i; |
328 | if(vname[0]!=0 && (vname[1]==0 || (vname[1]=='_' && vname[2]==0))) { |
||
329 | fast_setvar(vname,NULL); return; |
||
330 | } |
||
331 | i=search_list(mainvartab,mainvarcnt,sizeof(mainvartab[0]),vname); |
||
332 | if(i>=0) _setvar_(mainvartab+i,NULL); |
||
10 | reyssat | 333 | } |
334 | |||
7673 | bpr | 335 | /* Get a variable's value. */ |
10 | reyssat | 336 | char *_getvar(char *vname) |
337 | { |
||
12246 | bpr | 338 | char *val; |
339 | int i; |
||
10 | reyssat | 340 | |
12246 | bpr | 341 | if((untrust&4)!=0 || vname[0]==0) return ""; /* called from !readdef */ |
342 | if(vname[1]==0 || (vname[1]=='_' && vname[2]==0)) return fast_getvar(vname); |
||
343 | if((untrust&6)!=0) { |
||
344 | if(var_checkright(vname,var_readable,var_nr,var_pfx)==0) |
||
345 | return ""; |
||
346 | } |
||
347 | i=search_list(mainvartab,mainvarcnt,sizeof(mainvartab[0]),vname); |
||
348 | if(i<0) val=NULL; else { |
||
349 | if(mainvartab[i].tag&vb_hacked) { |
||
350 | add_hack(vname); mainvartab[i].tag&=~vb_hacked; |
||
10 | reyssat | 351 | } |
12246 | bpr | 352 | val=mainvartab[i].val; getvar_len=mainvartab[i].vlen; |
353 | } |
||
354 | if(vname[0]=='w' && strcmp(vname,"wims_incremental")==0) { |
||
355 | static char buf[32]; |
||
356 | if(val==NULL) i=0; |
||
357 | else i=atoi(val)+1; |
||
358 | mystrncpy(buf,int2str(i),sizeof(buf)); |
||
359 | force_setvar(vname,buf); getvar_len=strlen(buf); val=buf; |
||
360 | } |
||
361 | return val; |
||
10 | reyssat | 362 | } |
363 | |||
364 | char *getvar(char *vname) |
||
365 | { |
||
12246 | bpr | 366 | char *val; |
367 | getvar_len=0; val=_getvar(vname); |
||
368 | if(val==NULL && memcmp(vname,mathfont_prefix,strlen(mathfont_prefix))==0) {// mathfont_prefix m_ is add |
||
369 | val=mathfont(vname); |
||
370 | if(val) getvar_len=strlen(val); else getvar_len=0; |
||
371 | } |
||
372 | return val; |
||
10 | reyssat | 373 | } |
374 | |||
7673 | bpr | 375 | /* Search variables with numeric subscripts, from beg to end. |
8155 | bpr | 376 | * Store result to pbuf. Returns number of variables found. |
377 | */ |
||
10 | reyssat | 378 | int varsuite(char *stem, int beg, int end, char *pbuf[], int pbuflen) |
379 | { |
||
12246 | bpr | 380 | int i,t,l,v; |
381 | i=search_list(mainvartab,mainvarcnt,sizeof(mainvartab[0]),stem); |
||
382 | if(i<0) i=~i; |
||
383 | for(t=0,l=strlen(stem);i<mainvarcnt && t<pbuflen;i++){ |
||
384 | if(strncmp(mainvartab[i].name,stem,l)!=0) break; |
||
385 | v=atoi(mainvartab[i].name+l); if(v<beg || v>end) continue; |
||
386 | if(mainvartab[i].val==NULL || mainvartab[i].val[0]==0) continue; |
||
387 | pbuf[t++]=mainvartab[i].name; |
||
388 | } |
||
389 | return t; |
||
10 | reyssat | 390 | } |
391 | |||
7673 | bpr | 392 | /* output debug information */ |
10 | reyssat | 393 | void debug_output(void) |
394 | { |
||
12246 | bpr | 395 | long int endmtime2, time1; |
396 | struct timeval tv; |
||
397 | struct rusage us; |
||
10 | reyssat | 398 | |
12246 | bpr | 399 | if(noout || robot_access || strcasecmp(tmp_debug,"yes")!=0 || |
400 | checkhost(manager_site)<1) return; |
||
401 | if(instex_cnt>0) instex_flush(); |
||
402 | if(gettimeofday(&tv,NULL)) endmtime2=0; |
||
403 | else endmtime2=((tv.tv_sec%1000)*1000000+tv.tv_usec); |
||
404 | endmtime2=(endmtime2-startmtime2)/100; |
||
405 | time1=0; |
||
406 | if(getrusage(RUSAGE_SELF,&us)==0) { |
||
407 | time1+=us.ru_utime.tv_sec*1000+us.ru_utime.tv_usec/1000; |
||
408 | time1+=us.ru_stime.tv_sec*1000+us.ru_stime.tv_usec/1000; |
||
409 | } |
||
410 | if(getrusage(RUSAGE_CHILDREN,&us)==0) { |
||
411 | time1+=us.ru_utime.tv_sec*1000+us.ru_utime.tv_usec/1000; |
||
412 | time1+=us.ru_stime.tv_sec*1000+us.ru_stime.tv_usec/1000; |
||
413 | } |
||
414 | snprintf(tmplbuf,sizeof(tmplbuf),"%d,%d,%d,%.4f,%.2f,%d,%d,%d", |
||
415 | (int)(_varptr-_varbuf[_varbufcurr])+_varbufcurr*VARBUF_LEN, |
||
416 | bufvcnt-freevcnt,freevcnt, |
||
417 | (double) endmtime2/10000, (double) time1/1000, |
||
418 | mcachecnt,mfilecnt,execnt); |
||
419 | setvar("wims_debug_info",tmplbuf); |
||
420 | lastout_file=-1; phtml_put_base("debug.phtml",0); |
||
10 | reyssat | 421 | } |
422 | |||
7673 | bpr | 423 | /* Add to list of hacked variables */ |
10 | reyssat | 424 | void add_hack(char *name) |
425 | { |
||
12246 | bpr | 426 | char buf[MAX_LINELEN+1]; |
427 | char *p; |
||
428 | p=getvar("wims_hacked_variables"); if(p==NULL) buf[0]=0; |
||
429 | else snprintf(buf,sizeof(buf),"%s",p); |
||
430 | p=buf+strlen(buf); |
||
431 | if(p-buf >= sizeof(buf)-strlen(name)-4) return; /* too long */ |
||
432 | if(p>buf) snprintf(p,sizeof(buf)-(p-buf),", %s",name); |
||
433 | else snprintf(buf,sizeof(buf),"%s",name); |
||
434 | setvar("wims_hacked_variables",buf); |
||
10 | reyssat | 435 | } |