Subversion Repositories wimsdev

Rev

Rev 5333 | Rev 7646 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5333 Rev 5505
Line 12... Line 12...
12
 *
12
 *
13
 *  You should have received a copy of the GNU General Public License
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
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
16
 */
17
        /* line input / output / translation routines
17
      /* line input / output / translation routines
18
         * and error routines */
18
       * and error routines */
19
 
19
 
20
int is_class_module=0;
20
int is_class_module=0;
21
 
21
 
22
int trusted_module(void);
22
int trusted_module(void);
23
void phtml_put_base(char *fname,int cache);
23
void phtml_put_base(char *fname,int cache);
Line 40... Line 40...
40
char *outptr;
40
char *outptr;
41
 
41
 
42
  /* These modules can execute private programs.
42
  /* These modules can execute private programs.
43
   * adm/ modules are always trusted, so need no definition here. */
43
   * adm/ modules are always trusted, so need no definition here. */
44
char *trusted_modules="";
44
char *trusted_modules="";
45
                /* bit 0: module is not trusted.
45
            /* bit 0: module is not trusted.
46
                 * bit 1: file in wimshome.
46
             * bit 1: file in wimshome.
47
                 * bit 2: readdef or file in writable directory.
47
             * bit 2: readdef or file in writable directory.
48
                 */
48
             */
49
int untrust=0;  /* non-zero if user detrusts the module. */
49
int untrust=0;  /* non-zero if user detrusts the module. */
50
 
50
 
51
int error_status=0;
51
int error_status=0;
52
char pidbuf[32];
52
char pidbuf[32];
53
#include <utime.h>
53
#include <utime.h>
54
 
54
 
55
void delete_pid(void);
55
void delete_pid(void);
56
 
56
 
57
        /* Internal use only */
57
      /* Internal use only */
58
void _debug(char *s,...)
58
void _debug(char *s,...)
59
{
59
{
60
    va_list vp;
60
    va_list vp;
61
    char buf[MAX_LINELEN+1];
61
    char buf[MAX_LINELEN+1];
62
 
62
 
Line 66... Line 66...
66
    setvar("debug",buf); module_error("debug");
66
    setvar("debug",buf); module_error("debug");
67
    exit(1);
67
    exit(1);
68
}
68
}
69
 
69
 
70
 
70
 
71
        /* HTTP response header for non-processed CGI interface */
71
      /* HTTP response header for non-processed CGI interface */
72
void nph_header(int code)
72
void nph_header(int code)
73
{
73
{
74
    char *cstr;
74
    char *cstr;
75
    switch(code) {
75
    switch(code) {
76
        case 200: cstr="OK"; break;
76
      case 200: cstr="OK"; break;
77
        case 301: cstr="Moved Permanently"; break;
77
      case 301: cstr="Moved Permanently"; break;
78
        case 302: cstr="Moved Temporarily"; break;
78
      case 302: cstr="Moved Temporarily"; break;
79
        case 420: cstr="WIMS Nested Error"; break;
79
      case 420: cstr="WIMS Nested Error"; break;
80
        case 450: cstr="WIMS User Error"; break;
80
      case 450: cstr="WIMS User Error"; break;
81
        case 500: cstr="WIMS Internal Error"; break;
81
      case 500: cstr="WIMS Internal Error"; break;
82
        case 550: cstr="WIMS Module Error"; break;     
82
      case 550: cstr="WIMS Module Error"; break;      
83
        default: cstr="ERROR"; break;
83
      default: cstr="ERROR"; break;
84
    }
84
    }
85
    if(httpd_type!=httpd_wims) printf("Status: %d %s\r\n",code,cstr);
85
    if(httpd_type!=httpd_wims) printf("Status: %d %s\r\n",code,cstr);
86
    else {
86
    else {
87
        char *p, tbuf[256];
87
      char *p, tbuf[256];
88
        mystrncpy(tbuf,ctime(&nowtime),sizeof(tbuf));
88
      mystrncpy(tbuf,ctime(&nowtime),sizeof(tbuf));
89
        for(p=tbuf+strlen(tbuf);p>=tbuf && (*(p-1)=='\n' || *(p-1)=='\r'); p--);
89
      for(p=tbuf+strlen(tbuf);p>=tbuf && (*(p-1)=='\n' || *(p-1)=='\r'); p--);
90
        *p=0;
90
      *p=0;
91
        printf("HTTP/1.0 %d %s\r\n\
91
      printf("HTTP/1.0 %d %s\r\n\
92
Date: %s\r\n\
92
Date: %s\r\n\
93
Connection: close\r\n\
93
Connection: close\r\n\
94
",code,cstr,tbuf);
94
",code,cstr,tbuf);
95
    }
95
    }
96
}
96
}
Line 115... Line 115...
115
 
115
 
116
  /* Internal error: panic and forget about requester. */
116
  /* Internal error: panic and forget about requester. */
117
void internal_error(char msg[])
117
void internal_error(char msg[])
118
{
118
{
119
    if(error_status<2) {
119
    if(error_status<2) {
120
        nph_header(500);
120
      nph_header(500);
121
        printf("Cache-Control: no-cache\nPragma: no-cache\r\n\
121
      printf("Cache-Control: no-cache\nPragma: no-cache\r\n\
122
Content-type: text/plain\r\n\r\n\r\n\
122
Content-type: text/plain\r\n\r\n\r\n\
123
WIMS panick! %s\n%s\n",msg,strerror(errno));
123
WIMS panick! %s\n%s\n",msg,strerror(errno));
124
        error_status=2; internal_warn(msg);
124
      error_status=2; internal_warn(msg);
125
    }
125
    }
126
    delete_pid(); exit(1);
126
    delete_pid(); exit(1);
127
}
127
}
128
 
128
 
129
void tex_nospace(char *p)
129
void tex_nospace(char *p)
130
{
130
{
131
    char *p1, *p2;
131
    char *p1, *p2;
132
    char buf[MAX_LINELEN+1];
132
    char buf[MAX_LINELEN+1];
133
    for(p1=buf,p2=p;*p2 && p1-buf<MAX_LINELEN-4;p2++) {
133
    for(p1=buf,p2=p;*p2 && p1-buf<MAX_LINELEN-4;p2++) {
134
        if(!isspace(*p2)) {*p1++=*p2;continue;}
134
      if(!isspace(*p2)) {*p1++=*p2;continue;}
135
        while(isspace(*p2)) p2++;
135
      while(isspace(*p2)) p2++;
136
        if(*(p1-1)=='\\' ||
136
      if(*(p1-1)=='\\' ||
137
           (p1>buf && myisalnum(*(p1-1)) && myisalnum(*p2)))
137
         (p1>buf && myisalnum(*(p1-1)) && myisalnum(*p2)))
138
          *p1++=' ';
138
        *p1++=' ';
139
        *p1++=*p2;
139
      *p1++=*p2;
140
    }
140
    }
141
    *p1++=0; memmove(p,buf,p1-buf);
141
    *p1++=0; memmove(p,buf,p1-buf);
142
}
142
}
143
 
143
 
144
void nametoolong(char *p)
144
void nametoolong(char *p)
Line 150... Line 150...
150
}
150
}
151
 
151
 
152
enum{is_file, is_dir, is_exec, is_fifo, is_socket, is_unknown};
152
enum{is_file, is_dir, is_exec, is_fifo, is_socket, is_unknown};
153
off_t ftest_size;
153
off_t ftest_size;
154
 
154
 
155
        /* A simple front-end of stat(). */
155
      /* A simple front-end of stat(). */
156
int ftest(char *fname)
156
int ftest(char *fname)
157
{
157
{
158
    if(strcmp(fname,lastftest)==0) return lastftype;
158
    if(strcmp(fname,lastftest)==0) return lastftype;
159
/* if(fname[0]=='/' || fname[0]=='.') fprintf(stderr,"ftest: %s\n",fname); */
159
/* if(fname[0]=='/' || fname[0]=='.') fprintf(stderr,"ftest: %s\n",fname); */
160
    mystrncpy(lastftest,fname,sizeof(lastftest));
160
    mystrncpy(lastftest,fname,sizeof(lastftest));
161
    if(stat(fname,&ftst)) return lastftype=-1;
161
    if(stat(fname,&ftst)) return lastftype=-1;
162
    ftest_size=ftst.st_size;
162
    ftest_size=ftst.st_size;
163
    if(S_ISREG(ftst.st_mode)) {
163
    if(S_ISREG(ftst.st_mode)) {
164
        if((ftst.st_mode&(S_IXUSR|S_IXGRP|S_IXOTH))!=0) return lastftype=is_exec;
164
      if((ftst.st_mode&(S_IXUSR|S_IXGRP|S_IXOTH))!=0) return lastftype=is_exec;
165
        else return lastftype=is_file;
165
      else return lastftype=is_file;
166
    }
166
    }
167
    if(S_ISDIR(ftst.st_mode)) return lastftype=is_dir;
167
    if(S_ISDIR(ftst.st_mode)) return lastftype=is_dir;
168
    if(S_ISFIFO(ftst.st_mode)) return lastftype=is_fifo;
168
    if(S_ISFIFO(ftst.st_mode)) return lastftype=is_fifo;
169
    if(S_ISSOCK(ftst.st_mode)) return lastftype=is_socket;
169
    if(S_ISSOCK(ftst.st_mode)) return lastftype=is_socket;
170
    return lastftype=is_unknown;
170
    return lastftype=is_unknown;
171
}
171
}
172
 
172
 
173
char fnbuf[MAX_FNAME+1];
173
char fnbuf[MAX_FNAME+1];
174
 
174
 
175
        /* make a filename and check length */
175
      /* make a filename and check length */
176
char *mkfname(char buf[], char *s,...)
176
char *mkfname(char buf[], char *s,...)
177
{
177
{
178
    va_list vp;
178
    va_list vp;
179
    char *p;
179
    char *p;
180
 
180
 
Line 192... Line 192...
192
    struct stat st;
192
    struct stat st;
193
    mkfname(buf,"%s/%s",sysmask_trigger_dir,s);
193
    mkfname(buf,"%s/%s",sysmask_trigger_dir,s);
194
    stat(buf,&st);
194
    stat(buf,&st);
195
}
195
}
196
 
196
 
197
        /* read-in a file into buffer. Use open() and read().
197
      /* read-in a file into buffer. Use open() and read().
198
         * Return buffer address which will be malloc'ed if buf=NULL. */
198
       * Return buffer address which will be malloc'ed if buf=NULL. */
199
char *readfile(char *fname, char buf[], long int buflen)
199
char *readfile(char *fname, char buf[], long int buflen)
200
{
200
{
201
    int fd, t, st;
201
    int fd, t, st;
202
    long int l, lc;
202
    long int l, lc;
203
    char *bf;
203
    char *bf;
204
    t=0; if(buf) buf[0]=0;
204
    t=0; if(buf) buf[0]=0;
205
    st=ftest(fname); if(st!=is_file) {
205
    st=ftest(fname); if(st!=is_file) {
206
        if(st==is_exec) { /* refuse to open executable file */
206
      if(st==is_exec) { /* refuse to open executable file */
207
            setvar("executable",fname); module_error("executable");
207
          setvar("executable",fname); module_error("executable");
208
        }
208
      }
209
        return NULL;
209
      return NULL;
210
    }
210
    }
211
    l=ftst.st_size; if(l<0) return NULL;
211
    l=ftst.st_size; if(l<0) return NULL;
212
    if(l>=buflen) {
212
    if(l>=buflen) {
213
        if(buflen<MAX_LINELEN) l=buflen-1;
213
      if(buflen<MAX_LINELEN) l=buflen-1;
214
        else {
214
      else {
215
            if(strncmp(fname,"modules/",strlen("modules/"))==0) {
215
          if(strncmp(fname,"modules/",strlen("modules/"))==0) {
216
                setvar(error_data_string,fname); module_error("file_too_long");
216
            setvar(error_data_string,fname); module_error("file_too_long");
217
            }
217
          }
218
            else user_error("cmd_output_too_long");
218
          else user_error("cmd_output_too_long");
219
        }
219
      }
220
    }
220
    }
221
    fd=open(fname,O_RDONLY); if(fd==-1) return NULL;
221
    fd=open(fname,O_RDONLY); if(fd==-1) return NULL;
222
    if(buf==NULL) bf=xmalloc(l+8); else {bf=buf;if(l==0) {t=1; l=buflen-1;}}
222
    if(buf==NULL) bf=xmalloc(l+8); else {bf=buf;if(l==0) {t=1; l=buflen-1;}}
223
    lc=read(fd,bf,l); close(fd);
223
    lc=read(fd,bf,l); close(fd);
224
    if(lc<0 || lc>l || (lc!=l && t==0))
224
    if(lc<0 || lc>l || (lc!=l && t==0))
225
        {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
225
      {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
226
    bf[lc]=0; _tolinux(bf); return bf;
226
    bf[lc]=0; _tolinux(bf); return bf;
227
}
227
}
228
 
228
 
229
        /* Get a line in a stored working file.
229
      /* Get a line in a stored working file.
230
         * Buffer length is always MAX_LINELEN. */
230
       * Buffer length is always MAX_LINELEN. */
231
int wgetline(char buf[], size_t buflen, WORKING_FILE *f)
231
int wgetline(char buf[], size_t buflen, WORKING_FILE *f)
232
{
232
{
233
    int i,j; unsigned int n;
233
    int i,j; unsigned int n;
234
    i=f->linepointer; buf[0]=0;
234
    i=f->linepointer; buf[0]=0;
235
    if(i>=f->linecnt || f->textbuf==NULL) return EOF;
235
    if(i>=f->linecnt || f->textbuf==NULL) return EOF;
Line 245... Line 245...
245
{
245
{
246
    int i,l,flag;
246
    int i,l,flag;
247
    l=strlen(name); if(l>=127) return -1;
247
    l=strlen(name); if(l>=127) return -1;
248
    if(strncmp(module_prefix,module_dir,strlen(module_dir))!=0) flag=8; else flag=0;
248
    if(strncmp(module_prefix,module_dir,strlen(module_dir))!=0) flag=8; else flag=0;
249
    for(i=0;i<mcachecnt;i++) {
249
    for(i=0;i<mcachecnt;i++) {
250
        if(flag==mcache[i].nocache && strcmp(name,mcache[i].name)==0) {
250
      if(flag==mcache[i].nocache && strcmp(name,mcache[i].name)==0) {
251
            memmove(&m_file,mcache+i,sizeof(WORKING_FILE));
251
          memmove(&m_file,mcache+i,sizeof(WORKING_FILE));
252
            m_file.nocache|=4;
252
          m_file.nocache|=4;
253
            return i;
253
          return i;
254
        }
254
      }
255
    }
255
    }
256
    return -1;
256
    return -1;
257
}
257
}
258
 
258
 
259
        /* Open a work file. Returns 0 if OK. */
259
      /* Open a work file. Returns 0 if OK. */
260
int open_working_file(WORKING_FILE *f, char *fname)
260
int open_working_file(WORKING_FILE *f, char *fname)
261
{
261
{
262
    char *p, *q;
262
    char *p, *q;
263
    void *vp;
263
    void *vp;
264
    int i,j,k,laststart,lc[LINE_LIMIT];
264
    int i,j,k,laststart,lc[LINE_LIMIT];
Line 267... Line 267...
267
    f->for_idx=f->nocache=0;
267
    f->for_idx=f->nocache=0;
268
    f->l=-1; f->lines=NULL;
268
    f->l=-1; f->lines=NULL;
269
    f->textbuf=readfile(fname,NULL,WORKFILE_LIMIT);
269
    f->textbuf=readfile(fname,NULL,WORKFILE_LIMIT);
270
    if(f->textbuf==NULL) return -1;
270
    if(f->textbuf==NULL) return -1;
271
    p=f->textbuf; if(*p) {
271
    p=f->textbuf; if(*p) {
272
        for(i=0,p--; i<LINE_LIMIT-1 && p!=NULL;p=strchr(p,'\n')) {
272
      for(i=0,p--; i<LINE_LIMIT-1 && p!=NULL;p=strchr(p,'\n')) {
273
            if(i>0) *p=0;
273
          if(i>0) *p=0;
274
            lc[i++]=(++p-f->textbuf);
274
          lc[i++]=(++p-f->textbuf);
275
        }
275
      }
276
    }
276
    }
277
    else i=0;
277
    else i=0;
278
    if(i>=LINE_LIMIT-1) module_error("file_too_long");
278
    if(i>=LINE_LIMIT-1) module_error("file_too_long");
279
    lc[i]=lc[i-1]+strlen(f->textbuf+lc[i-1])+1;
279
    lc[i]=lc[i-1]+strlen(f->textbuf+lc[i-1])+1;
280
    f->textbuf[lc[i]]=0;
280
    f->textbuf[lc[i]]=0;
281
    f->linecnt=i; laststart=0;
281
    f->linecnt=i; laststart=0;
282
    f->for_stack=xmalloc(MAX_FOR_LEVEL*sizeof(FOR_STACK)+(i+1)*sizeof(LINE_STRUCT));
282
    f->for_stack=xmalloc(MAX_FOR_LEVEL*sizeof(FOR_STACK)+(i+1)*sizeof(LINE_STRUCT));
283
    vp=f->for_stack+MAX_FOR_LEVEL; f->lines=vp;
283
    vp=f->for_stack+MAX_FOR_LEVEL; f->lines=vp;
284
    for(j=0;j<i;j++) {
284
    for(j=0;j<i;j++) {
285
        f->lines[j].address=p=(f->textbuf)+lc[j];
285
      f->lines[j].address=p=(f->textbuf)+lc[j];
286
        f->lines[j].llen=lc[j+1]-lc[j]-1;
286
      f->lines[j].llen=lc[j+1]-lc[j]-1;
287
        (f->lines[j]).execcode=(f->lines[j]).varcode=-1;
287
      (f->lines[j]).execcode=(f->lines[j]).varcode=-1;
288
        if(j==0) goto normal;
288
      if(j==0) goto normal;
289
        q=f->lines[laststart].address+f->lines[laststart].llen-1;
289
      q=f->lines[laststart].address+f->lines[laststart].llen-1;
290
        if(q>=f->textbuf && *q=='\\') {
290
      if(q>=f->textbuf && *q=='\\') {
291
            f->lines[laststart].llen+=f->lines[j].llen; *q='\n';
291
          f->lines[laststart].llen+=f->lines[j].llen; *q='\n';
292
            f->lines[j].isstart=f->lines[j].llen=0;
292
          f->lines[j].isstart=f->lines[j].llen=0;
293
            memmove(q+1,p,lc[j+1]-lc[j]);
293
          memmove(q+1,p,lc[j+1]-lc[j]);
294
        }
294
      }
295
        else {
295
      else {
296
            normal: for(q=p;myislspace(*q);q++);
296
          normal: for(q=p;myislspace(*q);q++);
297
            f->lines[j].isstart=1; laststart=j; k=0;
297
          f->lines[j].isstart=1; laststart=j; k=0;
298
            switch(*q) {
298
          switch(*q) {
299
                        /* isstart: bit 1 = start.
299
                  /* isstart: bit 1 = start.
300
                         * bit 2 = exec
300
                   * bit 2 = exec
301
                         * bit 3 (4) = label
301
                   * bit 3 (4) = label
302
                         * bit 4 (8) = hard comment (!!)
302
                   * bit 4 (8) = hard comment (!!)
303
                         * bit 5 (16) = soft comment (#) */
303
                   * bit 5 (16) = soft comment (#) */
304
                case exec_prefix_char: {
304
            case exec_prefix_char: {
305
                    if(myisalpha(q[1])) f->lines[j].isstart=3;
305
                if(myisalpha(q[1])) f->lines[j].isstart=3;
306
                    else f->lines[j].isstart=9;
306
                else f->lines[j].isstart=9;
307
                    k=1; break;
307
                k=1; break;
308
                }
308
            }
309
                case label_prefix_char: {f->lines[j].isstart=5; k=1; break;}
309
            case label_prefix_char: {f->lines[j].isstart=5; k=1; break;}
310
                case comment_prefix_char: {f->lines[j].isstart=17; break;}
310
            case comment_prefix_char: {f->lines[j].isstart=17; break;}
311
                default: {f->lines[j].isstart=1; break;}
311
            default: {f->lines[j].isstart=1; break;}
312
            }
312
          }
313
            if(k && q>p) {f->lines[j].address=q;f->lines[j].llen-=q-p;}
313
          if(k && q>p) {f->lines[j].address=q;f->lines[j].llen-=q-p;}
314
        }
314
      }
315
    }
315
    }
316
    f->lines[i].isstart=1; f->lines[i].llen=0;
316
    f->lines[i].isstart=1; f->lines[i].llen=0;
317
    f->lines[i].address=(f->textbuf)+lc[i];
317
    f->lines[i].address=(f->textbuf)+lc[i];
318
    mfilecnt++; return 0;
318
    mfilecnt++; return 0;
319
}
319
}
320
 
320
 
321
        /* close an earlier opened working file */
321
      /* close an earlier opened working file */
322
void close_working_file(WORKING_FILE *f, int cache)
322
void close_working_file(WORKING_FILE *f, int cache)
323
{
323
{
324
    f->linepointer=f->l=0;
324
    f->linepointer=f->l=0;
325
    if(cache && untrust==0 && mcachecnt<MAX_MCACHE && (f->nocache&7)==0) {
325
    if(cache && untrust==0 && mcachecnt<MAX_MCACHE && (f->nocache&7)==0) {
326
        memmove(mcache+mcachecnt,f,sizeof(WORKING_FILE));
326
      memmove(mcache+mcachecnt,f,sizeof(WORKING_FILE));
327
        mcachecnt++;
327
      mcachecnt++;
328
    }
328
    }
329
    else if((f->nocache&4)==0) {
329
    else if((f->nocache&4)==0) {
330
        if(f->for_stack!=NULL) free(f->for_stack);
330
      if(f->for_stack!=NULL) free(f->for_stack);
331
        if(f->textbuf!=NULL) free(f->textbuf);
331
      if(f->textbuf!=NULL) free(f->textbuf);
332
    }
332
    }
333
    f->for_stack=NULL; f->textbuf=NULL; f->linecnt=0;
333
    f->for_stack=NULL; f->textbuf=NULL; f->linecnt=0;
334
}
334
}
335
 
335
 
336
void free_mcache(void)
336
void free_mcache(void)
Line 350... Line 350...
350
    nph_header(420);
350
    nph_header(420);
351
    printf("\r\n\r\nWIMS error processing aborted on nested error.\r\n\r\n%s\r\n",msg);
351
    printf("\r\n\r\nWIMS error processing aborted on nested error.\r\n\r\n%s\r\n",msg);
352
    delete_pid(); exit(1);
352
    delete_pid(); exit(1);
353
}
353
}
354
 
354
 
355
        /* Send an error message to requester and exit.
355
      /* Send an error message to requester and exit.
356
         * This is for user errors, language-sensitive. */
356
       * This is for user errors, language-sensitive. */
357
void user_error(char msg[])
357
void user_error(char msg[])
358
{
358
{
359
    char erfname[MAX_FNAME+1];
359
    char erfname[MAX_FNAME+1];
360
 
360
 
361
    if(error_status) nested_error(msg);
361
    if(error_status) nested_error(msg);
Line 365... Line 365...
365
Bad installation.");
365
Bad installation.");
366
    force_setvar("wims_user_error",msg);
366
    force_setvar("wims_user_error",msg);
367
    if(strcmp(msg,"threshold")!=0) user_error_log(msg);
367
    if(strcmp(msg,"threshold")!=0) user_error_log(msg);
368
    memmove(module_prefix,".",2);
368
    memmove(module_prefix,".",2);
369
    if(lastout_file!=-1 && outputing) {
369
    if(lastout_file!=-1 && outputing) {
370
        flushoutput(); close(lastout_file); lastout_file=-1;
370
      flushoutput(); close(lastout_file); lastout_file=-1;
371
    }
371
    }
372
    nph_header(450);
372
    nph_header(450);
373
    phtml_put_base(erfname,0);
373
    phtml_put_base(erfname,0);
374
    if(strcmp(msg,"double_click")!=0) delete_pid();
374
    if(strcmp(msg,"double_click")!=0) delete_pid();
375
    else {
375
    else {
376
        cleantmpdir(); flushlog();
376
      cleantmpdir(); flushlog();
377
    }
377
    }
378
    flushoutput(); exit(0);
378
    flushoutput(); exit(0);
379
}
379
}
380
 
380
 
381
void module_error_log(char msg[]);
381
void module_error_log(char msg[]);
382
 
382
 
383
        /* Messages for module errors. English only. */
383
      /* Messages for module errors. English only. */
384
        /* This is really rudimentary for the time being. */
384
      /* This is really rudimentary for the time being. */
385
void module_error(char msg[])
385
void module_error(char msg[])
386
{
386
{
387
    int send=0;
387
    int send=0;
388
    char *p;
388
    char *p;
389
    WORKING_FILE mf;
389
    WORKING_FILE mf;
Line 397... Line 397...
397
    if(p!=NULL && *p!=0) printf("Content-type: text/plain; charset=%s\r\n\r\n",p);
397
    if(p!=NULL && *p!=0) printf("Content-type: text/plain; charset=%s\r\n\r\n",p);
398
    else printf("Content-type: text/plain\r\n\r\n");
398
    else printf("Content-type: text/plain\r\n\r\n");
399
    p=getvar(ro_name[ro_module]); if(p==NULL) p="???";
399
    p=getvar(ro_name[ro_module]); if(p==NULL) p="???";
400
    printf("ERROR.\n\nwims has detected an error in the module '%s'.",p);
400
    printf("ERROR.\n\nwims has detected an error in the module '%s'.",p);
401
    if(m_file.l>=0) printf("\n\nIn file '%s', line %d:",
401
    if(m_file.l>=0) printf("\n\nIn file '%s', line %d:",
402
                           m_file.name,m_file.l+1);
402
                     m_file.name,m_file.l+1);
403
    printf(" %s.\n\n",msg);
403
    printf(" %s.\n\n",msg);
404
    if(open_working_file(&mf,mkfname(NULL,"%s.%s",module_error_msg_file,lang))!=0)
404
    if(open_working_file(&mf,mkfname(NULL,"%s.%s",module_error_msg_file,lang))!=0)
405
      internal_error("module_error(): error message file not found.");
405
      internal_error("module_error(): error message file not found.");
406
    while(wgetline(tmplbuf,MAX_LINELEN,&mf)!=EOF) {
406
    while(wgetline(tmplbuf,MAX_LINELEN,&mf)!=EOF) {
407
        if(tmplbuf[0]!=tag_prefix_char) {
407
      if(tmplbuf[0]!=tag_prefix_char) {
408
            if(send) {substit(tmplbuf); puts(tmplbuf);}
408
          if(send) {substit(tmplbuf); puts(tmplbuf);}
409
            continue;
409
          continue;
410
        }
410
      }
411
        strip_trailing_spaces(tmplbuf);
411
      strip_trailing_spaces(tmplbuf);
412
        if(tmplbuf[1]==0 || strcmp(msg,tmplbuf+1)==0) send=1;
412
      if(tmplbuf[1]==0 || strcmp(msg,tmplbuf+1)==0) send=1;
413
        else send=0;
413
      else send=0;
414
    }
414
    }
415
    close_working_file(&mf,0);
415
    close_working_file(&mf,0);
416
    outptr=outbuf; delete_pid(); exit(1);
416
    outptr=outbuf; delete_pid(); exit(1);
417
}
417
}
418
 
418
 
419
        /* Output kernel routine */
419
/* Output kernel routine */
420
void _output_(char *s)
420
void _output_(char *s)
421
{
421
{
422
    int l,l2;
422
    int l,l2;
423
    l=strlen(s); output_length+=l;
423
    l=strlen(s); output_length+=l;
424
    if(output_length>=OUTPUT_LENGTH_LIMIT) {
424
    if(output_length>=OUTPUT_LENGTH_LIMIT) {
425
        module_error("output_too_long"); return;
425
      module_error("output_too_long"); return;
426
    }
426
    }
427
    l2=sizeof(outbuf)-(outptr-outbuf);
427
    l2=sizeof(outbuf)-(outptr-outbuf);
428
    put: if(l<=l2) {
428
    put: if(l<=l2) {
429
        memmove(outptr,s,l); outptr+=l; return;
429
      memmove(outptr,s,l); outptr+=l; return;
430
    }
430
    }
431
    memmove(outptr,s,l2); s+=l2; l-=l2;
431
    memmove(outptr,s,l2); s+=l2; l-=l2;
432
    if(lastout_file!=-1) (void)write(lastout_file,outbuf,sizeof(outbuf));
432
    if(lastout_file!=-1) (void)write(lastout_file,outbuf,sizeof(outbuf));
433
    else fwrite(outbuf,sizeof(outbuf),1,stdout);
433
    else fwrite(outbuf,sizeof(outbuf),1,stdout);
434
    outptr=outbuf; l2=sizeof(outbuf); goto put;
434
    outptr=outbuf; l2=sizeof(outbuf); goto put;
435
}
435
}
436
 
436
 
437
        /* Output with no var. */
437
/* Output with no var. */
438
void output0(char buf[])
438
void output0(char buf[])
439
{
439
{
440
    char *p1, *p2, *ps;
440
    char *p1, *p2, *ps;
441
    int dynsave;
441
    int dynsave;
442
    if(backslash_insmath) {
442
    if(backslash_insmath) {
443
        ps=buf; dynsave=instex_usedynamic;
443
     ps=buf; dynsave=instex_usedynamic;
444
        for(p1=strstr(buf,"\\("); p1; p1=strstr(p2,"\\(")) {
444
     for(p1=strstr(buf,"\\("); p1; p1=strstr(p2,"\\(")) {
445
            p2=find_matching(p1+2,')');
445
         p2=find_matching(p1+2,')');
446
            if(p2==NULL) break;
446
         if(p2==NULL) break;
447
            if(p1>buf && *(p1-1)=='\\') continue;
447
         if(p1>buf && *(p1-1)=='\\') continue;
448
            *p1=0; if(*(p2-1)=='\\') *(p2-1)=0; *p2++=0; _output_(ps); ps=p2;
448
         *p1=0; if(*(p2-1)=='\\') *(p2-1)=0; *p2++=0; _output_(ps); ps=p2;
449
            instex_usedynamic=1; insmath(p1+2);
449
         instex_usedynamic=1; insmath(p1+2);
450
        }
450
     }
451
        if(*ps) _output_(ps); instex_usedynamic=dynsave;
451
     if(*ps) _output_(ps); instex_usedynamic=dynsave;
452
    }
452
    }
453
    else _output_(buf);
453
    else _output_(buf);
454
}
454
}
455
 
455
 
456
        /* Output routine */
456
/* Output routine */
457
void output(char *s,...)
457
void output(char *s,...)
458
{
458
{
459
    va_list vp;
459
    va_list vp;
460
    char buf[4*MAX_LINELEN+1];
460
    char buf[4*MAX_LINELEN+1];
461
 
461
 
Line 463... Line 463...
463
    vsnprintf(buf,sizeof(buf),s,vp);
463
    vsnprintf(buf,sizeof(buf),s,vp);
464
    va_end(vp);
464
    va_end(vp);
465
    output0(buf);
465
    output0(buf);
466
}
466
}
467
 
467
 
468
        /* read in tmpf in tmp directory, and places in p.
468
     /* read in tmpf in tmp directory, and places in p.
469
         * Maximal length: MAX_LINELEN. */
469
      * Maximal length: MAX_LINELEN. */
470
void read_tmp_file(char *p, const char *fname)
470
void read_tmp_file(char *p, const char *fname)
471
{
471
{
472
    char *name, *pp;
472
    char *name, *pp;
473
    name=mkfname(NULL,"%s/%s",tmp_dir,fname);
473
    name=mkfname(NULL,"%s/%s",tmp_dir,fname);
474
    if(!exec_is_module || !outputing || !direct_exec
474
    if(!exec_is_module || !outputing || !direct_exec
475
       || strcmp(fname,"exec.out")!=0) {
475
       || strcmp(fname,"exec.out")!=0) {
476
        readfile(name,p,MAX_LINELEN);
476
      readfile(name,p,MAX_LINELEN);
477
        pp=getvar("wims_exec_dollar_double");
477
      pp=getvar("wims_exec_dollar_double");
478
        if(pp && strcmp(pp,"yes")==0) {
478
      if(pp && strcmp(pp,"yes")==0) {
479
            for(pp=strchr(p,'$'); pp; pp=strchr(pp+2,'$'))
479
          for(pp=strchr(p,'$'); pp; pp=strchr(pp+2,'$'))
480
              string_modify(p,pp,pp+1,"$$");
480
            string_modify(p,pp,pp+1,"$$");
481
        }
481
      }
482
    }
482
    }
483
    else {
483
    else {
484
        char *s;
484
      char *s;
485
        s=readfile(name,NULL,OUTPUT_LENGTH_LIMIT);
485
      s=readfile(name,NULL,OUTPUT_LENGTH_LIMIT);
486
        if(s==NULL) {*p=0; return;}
486
      if(s==NULL) {*p=0; return;}
487
        if(memcmp(s,"Error: ", strlen("Error: "))==0) mystrncpy(p,s,MAX_LINELEN);
487
      if(memcmp(s,"Error: ", strlen("Error: "))==0) mystrncpy(p,s,MAX_LINELEN);
488
        output_length+=strlen(s);
488
      output_length+=strlen(s);
489
        if(output_length>=OUTPUT_LENGTH_LIMIT) module_error("output_too_long");
489
      if(output_length>=OUTPUT_LENGTH_LIMIT) module_error("output_too_long");
490
        else _output_(s);
490
      else _output_(s);
491
        free(s); *p=0;
491
      free(s); *p=0;
492
        chmod(name,S_IRUSR|S_IWUSR);
492
      chmod(name,S_IRUSR|S_IWUSR);
493
    }
493
    }
494
}
494
}
495
 
495
 
496
        /* verify whether the module is trusted.
496
      /* verify whether the module is trusted.
497
         * Returns 1 if yes, 0 if no. -1 for error. */
497
       * Returns 1 if yes, 0 if no. -1 for error. */
498
int trusted_module(void)
498
int trusted_module(void)
499
{
499
{
500
    char *modname, *w, buf[MAX_LINELEN+1];
500
    char *modname, *w, buf[MAX_LINELEN+1];
501
    int i,n;
501
    int i,n;
502
    static int _trusted=-1;     /* avoid repeated computations */
502
    static int _trusted=-1;      /* avoid repeated computations */
503
   
503
   
504
    if(untrust&255) return 0;
504
    if(untrust&255) return 0;
505
    if(_trusted>=0) return _trusted;
505
    if(_trusted>=0) return _trusted;
506
    modname=getvar(ro_name[ro_module]);
506
    modname=getvar(ro_name[ro_module]);
507
    if(modname==NULL || *modname==0) return 0;
507
    if(modname==NULL || *modname==0) return 0;
508
    if(memcmp(modname,"adm/",strlen("adm/"))==0 ||
508
    if(memcmp(modname,"adm/",strlen("adm/"))==0 ||
509
       memcmp(modname,"classes/",strlen("classes/"))==0 ||
509
       memcmp(modname,"classes/",strlen("classes/"))==0 ||
510
       strcmp(modname,home_module)==0 ||
510
       strcmp(modname,home_module)==0 ||
511
       memcmp(modname,"help/",strlen("help/"))==0) {
511
       memcmp(modname,"help/",strlen("help/"))==0) {
512
        tr:
512
      tr:
513
        if(memcmp(modname,"classes/",strlen("classes/"))==0)
513
      if(memcmp(modname,"classes/",strlen("classes/"))==0)
514
          is_class_module=1;
514
        is_class_module=1;
515
        setenv("trusted_module","yes",1);
515
      setenv("trusted_module","yes",1);
516
        return _trusted=1;
516
      return _trusted=1;
517
    }
517
    }
518
    n=wordnum(trusted_modules); for(i=0;i<n;i++) {
518
    n=wordnum(trusted_modules); for(i=0;i<n;i++) {
519
        w=fnd_word(trusted_modules,i+1,buf);
519
      w=fnd_word(trusted_modules,i+1,buf);
520
        if(strcmp(w,modname)==0) goto tr;
520
      if(strcmp(w,modname)==0) goto tr;
521
    }
521
    }
522
    return _trusted=0;
522
    return _trusted=0;
523
}
523
}
524
 
524
 
525
        /* file should be in the module directory, but
525
      /* file should be in the module directory, but
526
         * it may also be somewhere else.
526
       * it may also be somewhere else.
527
         * buf[] requires MAX_FNAME+1 length.
527
       * buf[] requires MAX_FNAME+1 length.
528
         * Returns 0 if found. */
528
       * Returns 0 if found. */
529
int find_module_file(char *fname, char buf[], int mode)
529
int find_module_file(char *fname, char buf[], int mode)
530
{
530
{
531
    char *p, dtest[32];
531
    char *p, dtest[32];
532
   
532
   
533
    fname=find_word_start(fname);
533
    fname=find_word_start(fname);
534
    if(*fname==0) return -1;
534
    if(*fname==0) return -1;
535
        /* Name checking: no directory backtracing. */
535
      /* Name checking: no directory backtracing. */
536
    if(strstr(fname,parent_dir_string)!=NULL) {
536
    if(strstr(fname,parent_dir_string)!=NULL) {
537
        setvar(error_data_string,fname); module_error("illegal_fname");
537
      setvar(error_data_string,fname); module_error("illegal_fname");
538
        return -1;
538
      return -1;
539
    }
539
    }
540
    p=strchr(fname,'/'); if(p==NULL || p>fname+10) goto openit;
540
    p=strchr(fname,'/'); if(p==NULL || p>fname+10) goto openit;
541
    memmove(dtest,fname,p-fname); dtest[p-fname]=0;
541
    memmove(dtest,fname,p-fname); dtest[p-fname]=0;
542
    if(strcmp(dtest,"datamodule")==0) {
542
    if(strcmp(dtest,"datamodule")==0) {
543
        mkfname(buf,"modules/data%s",p); goto lastopen;
543
      mkfname(buf,"modules/data%s",p); goto lastopen;
544
    }
544
    }
545
    if(strcmp(dtest,"wimshome")==0 && trusted_module()) {
545
    if(strcmp(dtest,"wimshome")==0 && trusted_module()) {
546
        mkfname(buf,"%s%s",getvar("wims_home"),p); goto lastopen;
546
      mkfname(buf,"%s%s",getvar("wims_home"),p); goto lastopen;
547
    }
547
    }
548
    if(strcmp(dtest,"writable")==0) {
548
    if(strcmp(dtest,"writable")==0) {
549
        if(strncmp(p+1,"TEMP_",5)==0 && strchr(p+1,'/')==NULL) {
549
      if(strncmp(p+1,"TEMP_",5)==0 && strchr(p+1,'/')==NULL) {
550
            mkfname(buf,"%s/%s",tmp_dir,p+1);
550
          mkfname(buf,"%s/%s",tmp_dir,p+1);
551
        }
551
      }
552
        else {
552
      else {
553
            mkfname(buf,"w/%s/%s",module_prefix,p+1);
553
          mkfname(buf,"w/%s/%s",module_prefix,p+1);
554
        }
554
      }
555
        untrust|=4;
555
      untrust|=4;
556
    }
556
    }
557
    else {
557
    else {
558
        openit: mkfname(buf,"%s/%s",module_prefix,fname);
558
      openit: mkfname(buf,"%s/%s",module_prefix,fname);
559
    }
559
    }
560
    if(mode) return 0;
560
    if(mode) return 0;
561
    if(ftest(buf)!=is_file) {
561
    if(ftest(buf)!=is_file) {
562
        if(lastftype==is_exec) {
562
      if(lastftype==is_exec) {
563
isexec:
563
isexec:
564
            setvar("executable",fname); module_error("executable");
564
          setvar("executable",fname); module_error("executable");
565
            return -1;
565
          return -1;
566
        }
566
      }
567
        if(strncmp(fname,"adm/",4)==0 &&
567
      if(strncmp(fname,"adm/",4)==0 &&
568
           (!trusted_module() || is_class_module)) return -1;
568
         (!trusted_module() || is_class_module)) return -1;
569
        mkfname(buf,"scripts/%s",fname);
569
      mkfname(buf,"scripts/%s",fname);
570
        lastopen:
570
      lastopen:
571
        if(mode) return 0;
571
      if(mode) return 0;
572
        if(ftest(buf)!=is_file) {
572
      if(ftest(buf)!=is_file) {
573
            if(lastftype==is_exec) goto isexec;
573
          if(lastftype==is_exec) goto isexec;
574
            else return -1;
574
          else return -1;
575
        }
575
      }
576
    }
576
    }
577
    return 0;
577
    return 0;
578
}
578
}
579
 
579
 
580
        /* check whether a file is user-submitted */
580
      /* check whether a file is user-submitted */
581
        /* This is deplecated because of the wimshome/ method. */
581
      /* This is deprecated because of the wimshome/ method. */
582
/* int user_file(char *name) {
582
/* int user_file(char *name) {
583
    if(name[0]=='/' || name[0]=='.' ||
583
    if(name[0]=='/' || name[0]=='.' ||
584
       strstr(name,"classes/")!=NULL ||
584
       strstr(name,"classes/")!=NULL ||
585
       strstr(name,"forums/")!=NULL ||
585
       strstr(name,"forums/")!=NULL ||
586
       strstr(name,"sessions/")!=NULL ||
586
       strstr(name,"sessions/")!=NULL ||
587
       strstr(name,"doc/")!=NULL) return 1; else return 0;
587
       strstr(name,"doc/")!=NULL) return 1; else return 0;
588
} */
588
} */
589
 
589
 
590
        /* returns 1 if violation */
590
      /* returns 1 if violation */
591
int datafile_check(char *name) {
591
int datafile_check(char *name) {
592
    if((untrust&255)==0) return 0;
592
    if((untrust&255)==0) return 0;
593
    if(strncmp(name,"data/",strlen("data/"))==0) return 0;
593
    if(strncmp(name,"data/",strlen("data/"))==0) return 0;
594
    if(strncmp(name,"authors/",strlen("authors/"))==0) return 0;
594
    if(strncmp(name,"authors/",strlen("authors/"))==0) return 0;
595
    if(strncmp(name,"datamodule/",strlen("datamodule/"))==0) return 0;
595
    if(strncmp(name,"datamodule/",strlen("datamodule/"))==0) return 0;
596
    return 1;
596
    return 1;
597
}
597
}
598
 
598
 
599
        /* returns 0 if success */
599
      /* returns 0 if success */
600
void readdatafile(char *name)
600
void readdatafile(char *name)
601
{
601
{
602
    char *pp;
602
    char *pp;
603
    if(strcmp(name,lastdatafile)==0) return;
603
    if(strcmp(name,lastdatafile)==0) return;
604
    lastdata[0]=0; readfile(name,lastdata,WORKFILE_LIMIT);
604
    lastdata[0]=0; readfile(name,lastdata,WORKFILE_LIMIT);
605
    mystrncpy(lastdatafile,name,sizeof(lastdatafile));
605
    mystrncpy(lastdatafile,name,sizeof(lastdatafile));
606
    datacache[0]=lastdata; nextdatacache=1;
606
    datacache[0]=lastdata; nextdatacache=1;
607
    if(lastdata[0]==tag_string[1]) {
607
    if(lastdata[0]==tag_string[1]) {
608
        datacache[1]=lastdata; nextdatacache++;
608
      datacache[1]=lastdata; nextdatacache++;
609
    }
609
    }
610
    pp=strstr(lastdata,tag_string);
610
    pp=strstr(lastdata,tag_string);
611
    if(pp) datacache[nextdatacache]=pp;
611
    if(pp) datacache[nextdatacache]=pp;
612
    else datacache[nextdatacache]=lastdata+strlen(lastdata);
612
    else datacache[nextdatacache]=lastdata+strlen(lastdata);
613
}
613
}
Line 619... Line 619...
619
    pp=strstr(p,tag_string);
619
    pp=strstr(p,tag_string);
620
    if(pp) return pp;
620
    if(pp) return pp;
621
    else return p+strlen(p);
621
    else return p+strlen(p);
622
}
622
}
623
 
623
 
624
        /* datafile structure: number of records.
624
      /* datafile structure: number of records.
625
         * tag=1 if direct access */
625
       * tag=1 if direct access */
626
unsigned int datafile_recordnum(char *p)
626
unsigned int datafile_recordnum(char *p)
627
{
627
{
628
    char nbuf[MAX_LINELEN+1], *pp;
628
    char nbuf[MAX_LINELEN+1], *pp;
629
    int i, t, ret;
629
    int i, t, ret;
630
 
630
 
631
    t=untrust; ret=0;
631
    t=untrust; ret=0;
632
    if(direct_datafile) mystrncpy(nbuf,p,sizeof(nbuf));
632
    if(direct_datafile) mystrncpy(nbuf,p,sizeof(nbuf));
633
    else if(datafile_check(p)!=0 || find_module_file(p,nbuf,0)) goto ret;
633
    else if(datafile_check(p)!=0 || find_module_file(p,nbuf,0)) goto ret;
634
    readdatafile(nbuf);
634
    readdatafile(nbuf);
635
    for(i=nextdatacache, pp=datacache[i]; *pp;) {
635
    for(i=nextdatacache, pp=datacache[i]; *pp;) {
636
        pp=_nextdata(pp+1); i++;
636
      pp=_nextdata(pp+1); i++;
637
        if(i<DATAFIELD_LIMIT) {
637
      if(i<DATAFIELD_LIMIT) {
638
            datacache[i]=pp; nextdatacache=i;
638
          datacache[i]=pp; nextdatacache=i;
639
        }
639
      }
640
    }
640
    }
641
    ret=i-1;
641
    ret=i-1;
642
    ret:
642
    ret:
643
    untrust=t;
643
    untrust=t;
644
    return ret;
644
    return ret;
645
}
645
}
646
 
646
 
647
        /* datafile structure: find record n, starting from 1 */
647
      /* datafile structure: find record n, starting from 1 */
648
char *datafile_fnd_record(char *p, int n, char bf[])
648
char *datafile_fnd_record(char *p, int n, char bf[])
649
{
649
{
650
    char nbuf[MAX_LINELEN+1], *pp, *p2;
650
    char nbuf[MAX_LINELEN+1], *pp, *p2;
651
    int i, t;
651
    int i, t;
652
 
652
 
Line 654... Line 654...
654
    if(n<0) goto ret;
654
    if(n<0) goto ret;
655
    if(direct_datafile) mystrncpy(nbuf,p,sizeof(nbuf));
655
    if(direct_datafile) mystrncpy(nbuf,p,sizeof(nbuf));
656
    else if(datafile_check(p)!=0 || find_module_file(p,nbuf,0)) goto ret;
656
    else if(datafile_check(p)!=0 || find_module_file(p,nbuf,0)) goto ret;
657
    readdatafile(nbuf); if(*lastdata==0) goto ret;
657
    readdatafile(nbuf); if(*lastdata==0) goto ret;
658
    if(n>nextdatacache) {
658
    if(n>nextdatacache) {
659
        for(i=nextdatacache, pp=datacache[i]; i<n && *pp;) {
659
      for(i=nextdatacache, pp=datacache[i]; i<n && *pp;) {
660
            pp=_nextdata(pp+1); i++;
660
          pp=_nextdata(pp+1); i++;
661
            if(i<DATAFIELD_LIMIT) {
661
          if(i<DATAFIELD_LIMIT) {
662
                datacache[i]=pp; nextdatacache=i;
662
            datacache[i]=pp; nextdatacache=i;
663
            }
663
          }
664
        }
664
      }
665
    }
665
    }
666
    else pp=datacache[n];
666
    else pp=datacache[n];
667
    if(!*pp) goto ret;
667
    if(!*pp) goto ret;
668
    if(n>1 || (n==1 && *pp!=tag_string[1])) pp+=strlen(tag_string);
668
    if(n>1 || (n==1 && *pp!=tag_string[1])) pp+=strlen(tag_string);
669
    else if(n==1) pp+=strlen(tag_string)-1;
669
    else if(n==1) pp+=strlen(tag_string)-1;
670
    if(n<nextdatacache) p2=datacache[n+1];
670
    if(n<nextdatacache) p2=datacache[n+1];
671
    else {
671
    else {
672
        p2=strstr(pp,tag_string); if(p2==NULL) p2=pp+strlen(pp);
672
      p2=strstr(pp,tag_string); if(p2==NULL) p2=pp+strlen(pp);
673
        if(n<DATAFIELD_LIMIT-1 && n==nextdatacache) {
673
      if(n<DATAFIELD_LIMIT-1 && n==nextdatacache) {
674
            nextdatacache++; datacache[nextdatacache]=p2;
674
          nextdatacache++; datacache[nextdatacache]=p2;
675
        }
675
      }
676
    }
676
    }
677
    if(p2-pp>=MAX_LINELEN) p2=pp+MAX_LINELEN-1;
677
    if(p2-pp>=MAX_LINELEN) p2=pp+MAX_LINELEN-1;
678
    if(p2<pp) p2=pp;
678
    if(p2<pp) p2=pp;
679
    memmove(bf,pp,p2-pp); bf[p2-pp]=0;
679
    memmove(bf,pp,p2-pp); bf[p2-pp]=0;
680
    ret:
680
    ret:
Line 684... Line 684...
684
char hex2char(char c1, char c2)
684
char hex2char(char c1, char c2)
685
{
685
{
686
    char tbuf[16];
686
    char tbuf[16];
687
    if(c1<'0' || c1>'f' || c2<'0' || c2>'f') {
687
    if(c1<'0' || c1>'f' || c2<'0' || c2>'f') {
688
invl:
688
invl:
689
        snprintf(tbuf,sizeof(tbuf),"%%%c%c",c1,c2);
689
      snprintf(tbuf,sizeof(tbuf),"%%%c%c",c1,c2);
690
        setvar(error_data_string,tbuf);
690
      setvar(error_data_string,tbuf);
691
        user_error("invalid_char_in_query_string");
691
      user_error("invalid_char_in_query_string");
692
    }
692
    }
693
    c1=toupper(c1);c2=toupper(c2);
693
    c1=toupper(c1);c2=toupper(c2);
694
    if(c1>'9' && c1<'A') goto invl;
694
    if(c1>'9' && c1<'A') goto invl;
695
    if(c2>'9' && c2<'A') goto invl;
695
    if(c2>'9' && c2<'A') goto invl;
696
    if(c1>'F' || c2>'F') goto invl;
696
    if(c1>'F' || c2>'F') goto invl;
697
    if(c1>='A') c1=c1-'A'+'9'+1;
697
    if(c1>='A') c1=c1-'A'+'9'+1;
698
    if(c2>='A') c2=c2-'A'+'9'+1;
698
    if(c2>='A') c2=c2-'A'+'9'+1;
699
    return (c1-'0')*16+c2-'0';
699
    return (c1-'0')*16+c2-'0';
700
}
700
}
701
 
701
 
702
        /* Converts back http escaped chars, slight. Does not check buffer length.
702
      /* Converts back http escaped chars, slight. Does not check buffer length.
703
         * Returns converted string length. */
703
       * Returns converted string length. */
704
int _http2env(char outs[], char ins[])
704
int _http2env(char outs[], char ins[])
705
{
705
{
706
    int j,k,l;
706
    int j,k,l;
707
    l=strlen(ins);
707
    l=strlen(ins);
708
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
708
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
709
        if(isspace(ins[j])) {  /* skip space characters in query string */
709
      if(isspace(ins[j])) {  /* skip space characters in query string */
710
            k--;continue;
710
          k--;continue;
711
        }
711
      }
712
        if(ins[j]=='%') {
712
      if(ins[j]=='%') {
713
              /* skip Carriage-Return. */
713
            /* skip Carriage-Return. */
714
            if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
714
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
715
                j+=2; k--; continue;
715
            j+=2; k--; continue;
716
            }
716
          }
717
            outs[k]=hex2char(ins[j+1],ins[j+2]);
717
          outs[k]=hex2char(ins[j+1],ins[j+2]);
718
            j+=2; continue;
718
          j+=2; continue;
719
        }
719
      }
720
        outs[k]=ins[j];
720
      outs[k]=ins[j];
721
    }
721
    }
722
    outs[k]=0;    
722
    outs[k]=0;    
723
    return k;
723
    return k;
724
}
724
}
725
 
725
 
726
        /* Converts back http escaped chars. Does not check buffer length.
726
      /* Converts back http escaped chars. Does not check buffer length.
727
         * Returns converted string length. */
727
       * Returns converted string length. */
728
int http2env(char outs[], char ins[])
728
int http2env(char outs[], char ins[])
729
{
729
{
730
    int j,k,l;
730
    int j,k,l;
731
    l=strlen(ins);
731
    l=strlen(ins);
732
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
732
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
733
        if(isspace(ins[j])) {  /* skip space characters in query string */
733
      if(isspace(ins[j])) {  /* skip space characters in query string */
734
            k--;continue;
734
          k--;continue;
735
        }
735
      }
736
        if(ins[j]=='%') {
736
      if(ins[j]=='%') {
737
              /* skip Carriage-Return. */
737
            /* skip Carriage-Return. */
738
            if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
738
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
739
                j+=2; k--; continue;
739
            j+=2; k--; continue;
740
            }
740
          }
741
            outs[k]=hex2char(ins[j+1],ins[j+2]);
741
          outs[k]=hex2char(ins[j+1],ins[j+2]);
742
            j+=2; continue;
742
          j+=2; continue;
743
        }
743
      }
744
        if(ins[j]=='+') {
744
      if(ins[j]=='+') {
745
            outs[k]=' '; continue;
745
          outs[k]=' '; continue;
746
        }
746
      }
747
        if(ins[j]=='?' || ins[j]=='&') {
747
      if(ins[j]=='?' || ins[j]=='&') {
748
            outs[k]=0; continue;
748
          outs[k]=0; continue;
749
        }
749
      }
750
        outs[k]=ins[j];
750
      outs[k]=ins[j];
751
    }
751
    }
752
    outs[k]=0;    
752
    outs[k]=0;    
753
    return k;
753
    return k;
754
}
754
}
755
 
755
 
756
        /* translate a string to http querystring style.
756
      /* translate a string to http querystring style.
757
         * '&' is not translated.
757
       * '&' is not translated.
758
         * Buffer p must be at least MAX_LINELEN. */
758
       * Buffer p must be at least MAX_LINELEN. */
759
void tohttpquery(char *p)
759
void tohttpquery(char *p)
760
{
760
{
761
    char trlist[]="     ()[]{}+-*^|/\"\'!:;,<>\n";
761
    char trlist[]="     ()[]{}+-*^|/\"\'!:;,<>\n";
762
    char *pp;
762
    char *pp;
763
    for(pp=p;*pp;pp++) {
763
    for(pp=p;*pp;pp++) {
764
        if(*pp==' ') {
764
      if(*pp==' ') {
765
            *pp='+'; continue;
765
          *pp='+'; continue;
766
        }
766
      }
767
        if(strchr(trlist,*pp)==NULL) continue;
767
      if(strchr(trlist,*pp)==NULL) continue;
768
        if(*pp=='+' && pp>p && *(pp-1)=='&') continue;
768
      if(*pp=='+' && pp>p && *(pp-1)=='&') continue;
769
        if(pp>p && *(pp-1)=='\\') {
769
      if(pp>p && *(pp-1)=='\\') {
770
            ovlstrcpy(pp-1,pp);pp--;continue;
770
          ovlstrcpy(pp-1,pp);pp--;continue;
771
        }
771
      }
772
        if(*pp=='\n') {
772
      if(*pp=='\n') {
773
            string_modify(p,pp,pp+1,"%%0D%%0A");pp+=5;
773
          string_modify(p,pp,pp+1,"%%0D%%0A");pp+=5;
774
        }
774
      }
775
        else {
775
      else {
776
            string_modify(p,pp,pp+1,"%%%02X",*pp);pp+=2;
776
          string_modify(p,pp,pp+1,"%%%02X",*pp);pp+=2;
777
        }
777
      }
778
    }
778
    }
779
}
779
}
780
 
780
 
781
        /* substitute backslash parameters. Internal use only. */
781
      /* substitute backslash parameters. Internal use only. */
782
void slashsubst(char *p)
782
void slashsubst(char *p)
783
{
783
{
784
    char *p1, *p2, *pt, *pp, namebuf[128];
784
    char *p1, *p2, *pt, *pp, namebuf[128];
785
    int n;
785
    int n;
786
 
786
 
787
    n=strlen(mathfont_prefix); memmove(namebuf,mathfont_prefix,n+1);
787
    n=strlen(mathfont_prefix); memmove(namebuf,mathfont_prefix,n+1);
788
    for(p1=strchr(p,'\\'); p1!=NULL; p1=strchr(p1,'\\')) {
788
    for(p1=strchr(p,'\\'); p1!=NULL; p1=strchr(p1,'\\')) {
789
        p1++; for(p2=p1; myisalnum(*p2) || *p2=='_'; p2++);
789
      p1++; for(p2=p1; myisalnum(*p2) || *p2=='_'; p2++);
790
        if(p2<=p1 || p2>p1+100) continue;
790
      if(p2<=p1 || p2>p1+100) continue;
791
        memmove(namebuf+n,p1,p2-p1); namebuf[p2-p1+n]=0;
791
      memmove(namebuf+n,p1,p2-p1); namebuf[p2-p1+n]=0;
792
        pt=_getvar(namebuf); if(pt==NULL) continue;
792
      pt=_getvar(namebuf); if(pt==NULL) continue;
793
        if(*p2=='[' && (pp=find_matching(p2+1,']'))!=NULL) {
793
      if(*p2=='[' && (pp=find_matching(p2+1,']'))!=NULL) {
794
            string_modify(p,pp+1,pp+1,")");
794
          string_modify(p,pp+1,pp+1,")");
795
            string_modify(p,p1-1,p1,"$(%s",mathfont_prefix);
795
          string_modify(p,p1-1,p1,"$(%s",mathfont_prefix);
796
        }
796
      }
797
        else string_modify(p,p1-1,p1,"$%s",mathfont_prefix);
797
      else string_modify(p,p1-1,p1,"$%s",mathfont_prefix);
798
    }
798
    }
799
}
799
}
800
 
800
 
801
        /* two alarm handlers. */
801
      /* two alarm handlers. */
802
void alarm1(int s)
802
void alarm1(int s)
803
{
803
{
804
    if(killpid>0 && kill(killpid,SIGKILL)) module_error("timeup");
804
    if(killpid>0 && kill(killpid,SIGKILL)) module_error("timeup");
805
    killpid=0;
805
    killpid=0;
806
}
806
}
Line 836... Line 836...
836
    if(signal(SIGALRM,alarm1)==SIG_ERR)
836
    if(signal(SIGALRM,alarm1)==SIG_ERR)
837
      internal_error(strerror(errno));
837
      internal_error(strerror(errno));
838
    alarm(limtimex-curr+1);
838
    alarm(limtimex-curr+1);
839
}
839
}
840
 
840
 
841
        /* create pid tag */
841
      /* create pid tag */
842
void create_pid(void)
842
void create_pid(void)
843
{
843
{
844
    char buf[MAX_FNAME+1], pbuf[256], obuf[MAX_FNAME+1];
844
    char buf[MAX_FNAME+1], pbuf[256], obuf[MAX_FNAME+1];
845
    struct stat dst;
845
    struct stat dst;
846
    struct utimbuf ub;
846
    struct utimbuf ub;
847
   
847
   
848
    if(robot_access || *session_prefix==0) return;
848
    if(robot_access || *session_prefix==0) return;
849
    if(cmd_type==cmd_getframe) return;
849
    if(cmd_type==cmd_getframe) return;
850
    mkfname(buf,"%s/.pid",s2_prefix);
850
    mkfname(buf,"%s/.pid",s2_prefix);
851
                /* another process running? */
851
            /* another process running? */
852
    if(readfile(buf,pbuf,sizeof(pbuf))!=NULL) {
852
    if(readfile(buf,pbuf,sizeof(pbuf))!=NULL) {
853
        mkfname(obuf,"/proc/%s",pbuf);
853
      mkfname(obuf,"/proc/%s",pbuf);
854
        if(stat(obuf,&dst)==0) user_error("double_click");
854
      if(stat(obuf,&dst)==0) user_error("double_click");
855
    }
855
    }
856
    snprintf(pidbuf,sizeof(pidbuf),"%u",getpid());
856
    snprintf(pidbuf,sizeof(pidbuf),"%u",getpid());
857
    accessfile(pidbuf,"w","%s",buf);
857
    accessfile(pidbuf,"w","%s",buf);
858
        /* Touch session time */
858
      /* Touch session time */
859
    if(strstr(session_prefix,"sessions/")==NULL) return;
859
    if(strstr(session_prefix,"sessions/")==NULL) return;
860
    ub.actime=ub.modtime=nowtime;
860
    ub.actime=ub.modtime=nowtime;
861
    utime(session_prefix,&ub);
861
    utime(session_prefix,&ub);
862
    if(strchr(session_prefix,'_')!=NULL) { /* touch parent too */
862
    if(strchr(session_prefix,'_')!=NULL) { /* touch parent too */
863
        char sbuf[MAX_FNAME+1], *p;
863
      char sbuf[MAX_FNAME+1], *p;
864
        mystrncpy(sbuf,session_prefix,sizeof(sbuf));
864
      mystrncpy(sbuf,session_prefix,sizeof(sbuf));
865
        p=strchr(sbuf,'_'); if(p!=NULL) *p=0;
865
      p=strchr(sbuf,'_'); if(p!=NULL) *p=0;
866
        utime(sbuf,&ub);
866
      utime(sbuf,&ub);
867
    }
867
    }
868
}
868
}
869
 
869
 
870
struct {
870
struct {
871
    char cmd[MAX_EXEC_NAME+1];
871
    char cmd[MAX_EXEC_NAME+1];
Line 881... Line 881...
881
    pid_t pid;
881
    pid_t pid;
882
    int status, t;
882
    int status, t;
883
 
883
 
884
    if(robot_access) return 0;
884
    if(robot_access) return 0;
885
    if(time(0)>=limtimex) {
885
    if(time(0)>=limtimex) {
886
        if(errf!=NULL)
886
      if(errf!=NULL)
887
          accessfile("No time left to execute subprograms.\n","w","%s",errf);
887
        accessfile("No time left to execute subprograms.\n","w","%s",errf);
888
        return -100;
888
      return -100;
889
    }
889
    }
890
    lastdatafile[0]=lastftest[0]=0;
890
    lastdatafile[0]=lastftest[0]=0;
891
    fflush(NULL);       /* flush all output streams before forking
891
    fflush(NULL);      /* flush all output streams before forking
892
                         * otherwise they will be doubled */
892
                   * otherwise they will be doubled */
893
    pid=fork(); if(pid==-1) return -1;
893
    pid=fork(); if(pid==-1) return -1;
894
    if(!pid) {  /* child */
894
    if(!pid) {      /* child */
895
        char buf[MAX_LINELEN+1]; int k;
895
      char buf[MAX_LINELEN+1]; int k;
896
        (void)nice(10); /* lower priority for children */
896
      (void)nice(10);      /* lower priority for children */
897
        if(is_multiexec) {
897
      if(is_multiexec) {
898
            dup2(mxtab[multiexec_index].pipe_stdin[0],0);
898
          dup2(mxtab[multiexec_index].pipe_stdin[0],0);
899
            dup2(mxtab[multiexec_index].pipe_stdout[1],1);
899
          dup2(mxtab[multiexec_index].pipe_stdout[1],1);
900
            dup2(mxtab[multiexec_index].pipe_stderr[1],2);
900
          dup2(mxtab[multiexec_index].pipe_stderr[1],2);
901
        }
901
      }
902
        else {
902
      else {
903
            if(inf!=NULL) (void)freopen(inf,"r",stdin);
903
          if(inf!=NULL) (void)freopen(inf,"r",stdin);
904
            if(outf!=NULL) (void)freopen(outf,"w",stdout);
904
          if(outf!=NULL) (void)freopen(outf,"w",stdout);
905
            if(errf!=NULL) (void)freopen(errf,"w",stderr);
905
          if(errf!=NULL) (void)freopen(errf,"w",stderr);
906
        }
906
      }
907
                /* This is to patch LinuxPPC uid wrapping
907
            /* This is to patch LinuxPPC uid wrapping
908
                 * for scripts */
908
             * for scripts */
909
        t=0; if(strchr(cmdf,'/')) {
909
      t=0; if(strchr(cmdf,'/')) {
910
            int tf;
910
          int tf;
911
            char tbuf[16];
911
          char tbuf[16];
912
            tf=open(cmdf,O_RDONLY); (void)read(tf,tbuf,8); close(tf);
912
          tf=open(cmdf,O_RDONLY); (void)read(tf,tbuf,8); close(tf);
913
            if(memcmp(tbuf+1,"ELF",3)!=0) t=1;
913
          if(memcmp(tbuf+1,"ELF",3)!=0) t=1;
914
        }
914
      }
915
        if(wrapexec==-1) {
915
      if(wrapexec==-1) {
916
            setreuid(getuid(),getuid());setregid(getgid(),getgid());
916
          setreuid(getuid(),getuid());setregid(getgid(),getgid());
917
        }
917
      }
918
        if(wrapexec==1 || (t==1 && wrapexec==0)) {
918
      if(wrapexec==1 || (t==1 && wrapexec==0)) {
919
            setreuid(geteuid(),geteuid());setregid(getegid(),getegid());
919
          setreuid(geteuid(),geteuid());setregid(getegid(),getegid());
920
        }
920
      }
921
        errno=0;
921
      errno=0;
922
        if(strchr(cmdf,'/')) execve(cmdf,arg,environ);
922
      if(strchr(cmdf,'/')) execve(cmdf,arg,environ);
923
        else execvp(cmdf,arg);
923
      else execvp(cmdf,arg);
924
        snprintf(buf,sizeof(buf),"Failed to execute");
924
      snprintf(buf,sizeof(buf),"Failed to execute");
925
        for(k=0;arg[k];k++) {
925
      for(k=0;arg[k];k++) {
926
            t=strlen(buf);
926
          t=strlen(buf);
927
            snprintf(buf+t,sizeof(buf)-t," %s",arg[k]);
927
          snprintf(buf+t,sizeof(buf)-t," %s",arg[k]);
928
        }
928
      }
929
        t=strlen(buf);
929
      t=strlen(buf);
930
        snprintf(buf+t,sizeof(buf)-t,"\n        %s\n",strerror(errno));
930
      snprintf(buf+t,sizeof(buf)-t,"\n  %s\n",strerror(errno));
931
        accessfile(buf,"a","%s/exec.fail",tmp_dir);
931
      accessfile(buf,"a","%s/exec.fail",tmp_dir);
932
        exit(127);
932
      exit(127);
933
    }
933
    }
934
    else {      /* parent */
934
    else {      /* parent */
935
        wrapexec=0; status=0;
935
      wrapexec=0; status=0;
936
        if(exec_wait && !is_multiexec) {
936
      if(exec_wait && !is_multiexec) {
937
            killpid=pid; forkalarm();
937
          killpid=pid; forkalarm();
938
            waitpid(pid,&status,0); killpid=0; finalalarm();
938
          waitpid(pid,&status,0); killpid=0; finalalarm();
939
        }
939
      }
940
        return WEXITSTATUS(status);
940
      return WEXITSTATUS(status);
941
    }
941
    }
942
}
942
}
943
 
943
 
944
        /* preparation for resident execution.
944
      /* preparation for resident execution.
945
         * Returns 1 if already up, otherwise 0. */
945
       * Returns 1 if already up, otherwise 0. */
946
int multiexec(char *cmd, char **abuf)
946
int multiexec(char *cmd, char **abuf)
947
{
947
{
948
    char *p;
948
    char *p;
949
    int i;
949
    int i;
950
   
950
   
Line 953... Line 953...
953
    if(strstr(tmp_debug,"yes")!=NULL && checkhost(manager_site)>=1)
953
    if(strstr(tmp_debug,"yes")!=NULL && checkhost(manager_site)>=1)
954
      setenv("multiexec_debug","yes",1);
954
      setenv("multiexec_debug","yes",1);
955
    p=getvar("wims_multiexec");
955
    p=getvar("wims_multiexec");
956
    if(p==NULL || wordchr(p,cmd)==NULL) return 0; /* not allowed */
956
    if(p==NULL || wordchr(p,cmd)==NULL) return 0; /* not allowed */
957
    if(!multiexec_random[0]) {
957
    if(!multiexec_random[0]) {
958
        snprintf(multiexec_random, sizeof(multiexec_random),
958
      snprintf(multiexec_random, sizeof(multiexec_random),
959
                 "%lX%lX%lX%lX%lX%lX%lX%lX",
959
             "%lX%lX%lX%lX%lX%lX%lX%lX",
960
                 random(),random(),random(),random(),
960
             random(),random(),random(),random(),
961
                 random(),random(),random(),random());
961
             random(),random(),random(),random());
962
        setenv("multiexec_random",multiexec_random,1);
962
      setenv("multiexec_random",multiexec_random,1);
963
    }
963
    }
964
    for(i=0;i<mxno && strcmp(cmd,mxtab[i].cmd)!=0; i++);
964
    for(i=0;i<mxno && strcmp(cmd,mxtab[i].cmd)!=0; i++);
965
    multiexec_index=i;
965
    multiexec_index=i;
966
    if(i==mxno) {
966
    if(i==mxno) {
967
        if(mxno>=MAX_MULTIEXEC) return 0;
967
      if(mxno>=MAX_MULTIEXEC) return 0;
968
        if(pipe(mxtab[i].pipe_stdin)<0) return 0;
968
      if(pipe(mxtab[i].pipe_stdin)<0) return 0;
969
        if(pipe(mxtab[i].pipe_stdout)<0) return 0;
969
      if(pipe(mxtab[i].pipe_stdout)<0) return 0;
970
        if(pipe(mxtab[i].pipe_stderr)<0) return 0;
970
      if(pipe(mxtab[i].pipe_stderr)<0) return 0;
971
        mystrncpy(mxtab[i].cmd,cmd,sizeof(mxtab[i].cmd));
971
      mystrncpy(mxtab[i].cmd,cmd,sizeof(mxtab[i].cmd));
972
        mxno++; is_multiexec=1;
972
      mxno++;      is_multiexec=1;
973
        exportall(); setenv("wims_exec_parm",multiexec_random,1);
973
      exportall(); setenv("wims_exec_parm",multiexec_random,1);
974
        execredirected(abuf[0],NULL,NULL,NULL,abuf);
974
      execredirected(abuf[0],NULL,NULL,NULL,abuf);
975
    }
975
    }
976
    is_multiexec=0;
976
    is_multiexec=0;
977
    return 1;
977
    return 1;
978
}
978
}
979
 
979
 
980
        /* my system(), but with variable parms
980
      /* my system(), but with variable parms
981
         * More secure than system(), and direct fork. */
981
       * More secure than system(), and direct fork. */
982
int call_ssh(char *s,...)
982
int call_ssh(char *s,...)
983
{
983
{
984
    va_list vp;
984
    va_list vp;
985
    char buf[MAX_LINELEN+1];
985
    char buf[MAX_LINELEN+1];
986
    char *arg[1024];
986
    char *arg[1024];
Line 993... Line 993...
993
    vsnprintf(buf,sizeof(buf),s,vp);
993
    vsnprintf(buf,sizeof(buf),s,vp);
994
    va_end(vp);
994
    va_end(vp);
995
    p=find_word_start(buf); if(*p==0) return 0;
995
    p=find_word_start(buf); if(*p==0) return 0;
996
    cmdf=p;
996
    cmdf=p;
997
    for(i=0;*p!=0 && i<1000; p=find_word_start(p2)) {
997
    for(i=0;*p!=0 && i<1000; p=find_word_start(p2)) {
998
        switch(*p) {
998
      switch(*p) {
999
            case '\'': {
999
          case '\'': {
1000
                p++; p2=strchr(p,'\''); if(p2==NULL) p2=p+strlen(p);
1000
            p++; p2=strchr(p,'\''); if(p2==NULL) p2=p+strlen(p);
1001
                d=0; break;
1001
            d=0; break;
1002
            }
1002
          }
1003
            case '"': {
1003
          case '"': {
1004
                p++; p2=strchr(p,'"'); if(p2==NULL) p2=p+strlen(p);
1004
            p++; p2=strchr(p,'"'); if(p2==NULL) p2=p+strlen(p);
1005
                d=0; break;
1005
            d=0; break;
1006
            }
1006
          }
1007
            default: d=1; p2=find_word_end(p); break;
1007
          default: d=1; p2=find_word_end(p); break;
1008
        }
1008
      }
1009
        if(*p2) *p2++=0;
1009
      if(*p2) *p2++=0;
1010
        if(!d) {arg[i++]=p; continue;}
1010
      if(!d) {arg[i++]=p; continue;}
1011
        switch(*p) {
1011
      switch(*p) {
1012
            case '<': inf=++p; break;
1012
          case '<': inf=++p; break;
1013
            case '>': {
1013
          case '>': {
1014
                p++; if(*p=='&') {
1014
            p++; if(*p=='&') {
1015
                    merge: p++; errf=outf=p; break;
1015
                merge: p++; errf=outf=p; break;
1016
                }
1016
            }
1017
                else outf=p;
1017
            else outf=p;
1018
                break;
1018
            break;
1019
            }
1019
          }
1020
            case '&': {
1020
          case '&': {
1021
                p++; if(*p=='>') goto merge;
1021
            p++; if(*p=='>') goto merge;
1022
                else break;
1022
            else break;
1023
            }
1023
          }
1024
            case '2': {
1024
          case '2': {
1025
                if(*(p+1)=='>') {errf=p+2; break;}
1025
            if(*(p+1)=='>') {errf=p+2; break;}
1026
            }
1026
          }
1027
            default: arg[i++]=p; break;
1027
          default: arg[i++]=p; break;
1028
        }
1028
      }
1029
    }
1029
    }
1030
    arg[i]=NULL;
1030
    arg[i]=NULL;
1031
    return execredirected(cmdf,inf,outf,errf,arg);
1031
    return execredirected(cmdf,inf,outf,errf,arg);
1032
}
1032
}
1033
 
1033
 
1034
        /* Read/write to a file with variable parms to print filename */
1034
      /* Read/write to a file with variable parms to print filename */
1035
void accessfile(char *content, char *type, char *s,...)
1035
void accessfile(char *content, char *type, char *s,...)
1036
{
1036
{
1037
    va_list vp;
1037
    va_list vp;
1038
    char buf[MAX_FNAME+1];
1038
    char buf[MAX_FNAME+1];
1039
    int fd;
1039
    int fd;
Line 1042... Line 1042...
1042
    va_start(vp,s);
1042
    va_start(vp,s);
1043
    vsnprintf(buf,sizeof(buf),s,vp);
1043
    vsnprintf(buf,sizeof(buf),s,vp);
1044
    va_end(vp);
1044
    va_end(vp);
1045
    if(strlen(buf)>=MAX_FNAME-1) nametoolong(buf);
1045
    if(strlen(buf)>=MAX_FNAME-1) nametoolong(buf);
1046
    switch(*type) {
1046
    switch(*type) {
1047
        case 'r': readfile(buf,content,MAX_LINELEN); return;
1047
      case 'r': readfile(buf,content,MAX_LINELEN); return;
1048
        case 'e': readfile(buf,content,MAX_LINELEN/4); return;  /* limited read */
1048
      case 'e': readfile(buf,content,MAX_LINELEN/4); return; /* limited read */
1049
        case 'w': fd=creat(buf,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); break;
1049
      case 'w': fd=creat(buf,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); break;
1050
        case 'a': fd=open(buf,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); break;
1050
      case 'a': fd=open(buf,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); break;
1051
        default : return;
1051
      default : return;
1052
    }
1052
    }
1053
    lastdatafile[0]=lastftest[0]=0;
1053
    lastdatafile[0]=lastftest[0]=0;
1054
    if(fd==-1) return;
1054
    if(fd==-1) return;
1055
    (void)write(fd,content,strlen(content)); close(fd);
1055
    (void)write(fd,content,strlen(content)); close(fd);
1056
}
1056
}
1057
 
1057
 
1058
        /* system(), but with variable parms
1058
      /* system(), but with variable parms
1059
         * Uses sh to execute command. */
1059
       * Uses sh to execute command. */
1060
int call_sh(char *s,...)
1060
int call_sh(char *s,...)
1061
{
1061
{
1062
    va_list vp;
1062
    va_list vp;
1063
    char buf[MAX_LINELEN+1];
1063
    char buf[MAX_LINELEN+1];
1064
    char *abuf[8];
1064
    char *abuf[8];
Line 1073... Line 1073...
1073
 
1073
 
1074
void _getdef(char buf[], char *name, char value[])
1074
void _getdef(char buf[], char *name, char value[])
1075
{
1075
{
1076
    char *p1, *p2, *p3, *p4;
1076
    char *p1, *p2, *p3, *p4;
1077
 
1077
 
1078
    if(*name==0) goto nothing;  /* this would create segfault. */
1078
    if(*name==0) goto nothing;      /* this would create segfault. */
1079
    for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
1079
    for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
1080
        p2=find_word_start(p1+strlen(name));
1080
      p2=find_word_start(p1+strlen(name));
1081
        if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue;
1081
      if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue;
1082
        p3=p1; while(p3>buf && *(p3-1)!='\n') p3--;
1082
      p3=p1; while(p3>buf && *(p3-1)!='\n') p3--;
1083
        p3=find_word_start(p3);
1083
      p3=find_word_start(p3);
1084
        if(p3<p1 && *p3!='!') continue;
1084
      if(p3<p1 && *p3!='!') continue;
1085
        if(p3<p1) {
1085
      if(p3<p1) {
1086
            p3++; p4=find_word_end(p3);
1086
          p3++; p4=find_word_end(p3);
1087
            if(find_word_start(p4)!=p1) continue;
1087
          if(find_word_start(p4)!=p1) continue;
1088
            if(p4-p3!=3 || (strncmp(p3,"set",3)!=0 &&
1088
          if(p4-p3!=3 || (strncmp(p3,"set",3)!=0 &&
1089
               strncmp(p3,"let",3)!=0 &&
1089
             strncmp(p3,"let",3)!=0 &&
1090
               strncmp(p3,"def",3)!=0)) {
1090
             strncmp(p3,"def",3)!=0)) {
1091
                if(p4-p3!=6 || strncmp(p3,"define",6)!=0) continue;
1091
            if(p4-p3!=6 || strncmp(p3,"define",6)!=0) continue;
1092
            }
1092
          }
1093
        }
1093
      }
1094
        p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2);
1094
      p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2);
1095
        p2=find_word_start(p2);
1095
      p2=find_word_start(p2);
1096
        if(p2>p3) goto nothing;
1096
      if(p2>p3) goto nothing;
1097
        if(p3-p2>=MAX_LINELEN) user_error("cmd_output_too_long");
1097
      if(p3-p2>=MAX_LINELEN) user_error("cmd_output_too_long");
1098
        memmove(value,p2,p3-p2); value[p3-p2]=0;
1098
      memmove(value,p2,p3-p2); value[p3-p2]=0;
1099
        strip_trailing_spaces(value); return;
1099
      strip_trailing_spaces(value); return;
1100
    }
1100
    }
1101
nothing:
1101
nothing:
1102
    value[0]=0; return;
1102
    value[0]=0; return;
1103
}
1103
}
1104
 
1104
 
1105
        /* Get variable definition from a file.
1105
      /* Get variable definition from a file.
1106
         * Result stored in buffer value of length MAX_LINELEN. */
1106
       * Result stored in buffer value of length MAX_LINELEN. */
1107
void getdef(char *fname, char *name, char value[])
1107
void getdef(char *fname, char *name, char value[])
1108
{
1108
{
1109
    char buf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1], nbuf[MAX_NAMELEN+1];
1109
    char buf[MAX_LINELEN+1], tbuf[MAX_LINELEN+1], nbuf[MAX_NAMELEN+1];
1110
    char *p1, *p2;
1110
    char *p1, *p2;
1111
 
1111
 
1112
    value[0]=0; if(readfile(fname,buf,sizeof(buf)-16)==NULL) return;
1112
    value[0]=0; if(readfile(fname,buf,sizeof(buf)-16)==NULL) return;
1113
    mystrncpy(value,name,MAX_LINELEN);
1113
    mystrncpy(value,name,MAX_LINELEN);
1114
    for(p1=value; *p1; p1=p2) {
1114
    for(p1=value; *p1; p1=p2) {
1115
        while(*p1 && !myisalnum(*p1) && *p1!='_') p1++;
1115
      while(*p1 && !myisalnum(*p1) && *p1!='_') p1++;
1116
        if(*p1==0) break;
1116
      if(*p1==0) break;
1117
        for(p2=p1; myisalnum(*p2) || *p2=='_'; p2++);
1117
      for(p2=p1; myisalnum(*p2) || *p2=='_'; p2++);
1118
        if(p2-p1>MAX_NAMELEN) continue;
1118
      if(p2-p1>MAX_NAMELEN) continue;
1119
        memmove(nbuf,p1,p2-p1); nbuf[p2-p1]=0;
1119
      memmove(nbuf,p1,p2-p1); nbuf[p2-p1]=0;
1120
        _getdef(buf,nbuf,tbuf);
1120
      _getdef(buf,nbuf,tbuf);
1121
        string_modify(value,p1,p2,"%s",tbuf);
1121
      string_modify(value,p1,p2,"%s",tbuf);
1122
        p2=p1+strlen(tbuf);
1122
      p2=p1+strlen(tbuf);
1123
    }
1123
    }
1124
}
1124
}
1125
 
1125
 
1126
int _setdef_changed;
1126
int _setdef_changed;
1127
 
1127
 
Line 1129... Line 1129...
1129
{
1129
{
1130
    char *p1, *p2, *p3;
1130
    char *p1, *p2, *p3;
1131
    int n;
1131
    int n;
1132
   
1132
   
1133
    for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
1133
    for(p1=strstr(buf,name); p1!=NULL; p1=strstr(p1+1,name)) {
1134
        p2=find_word_start(p1+strlen(name));
1134
      p2=find_word_start(p1+strlen(name));
1135
        if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue;
1135
      if((p1>buf && !isspace(*(p1-1))) || *p2!='=') continue;
1136
        p3=p1; while(p3>buf && *(p3-1)==' ') p3--;
1136
      p3=p1; while(p3>buf && *(p3-1)==' ') p3--;
1137
        if(p3>buf && *(p3-1)!='\n') continue;
1137
      if(p3>buf && *(p3-1)!='\n') continue;
1138
        p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2);
1138
      p2++;p3=strchr(p2,'\n'); if(p3==NULL) p3=p2+strlen(p2);
1139
        if(strlen(value)!=p3-p2 || strncmp(value,p2,p3-p2)!=0) {
1139
      if(strlen(value)!=p3-p2 || strncmp(value,p2,p3-p2)!=0) {
1140
            string_modify(buf,p2,p3,"%s",value);
1140
          string_modify(buf,p2,p3,"%s",value);
1141
            _setdef_changed++;
1141
          _setdef_changed++;
1142
        }
1142
      }
1143
        return;
1143
      return;
1144
    }
1144
    }
1145
    n=strlen(buf);
1145
    n=strlen(buf);
1146
    if(n>0 && buf[n-1]!='\n')
1146
    if(n>0 && buf[n-1]!='\n')
1147
      snprintf(buf+n,MAX_LINELEN-n,"\n%s=%s\n",name,value);
1147
      snprintf(buf+n,MAX_LINELEN-n,"\n%s=%s\n",name,value);
1148
    else
1148
    else
1149
      snprintf(buf+n,MAX_LINELEN-n,"%s=%s\n",name,value);
1149
      snprintf(buf+n,MAX_LINELEN-n,"%s=%s\n",name,value);
1150
    _setdef_changed++;
1150
    _setdef_changed++;
1151
}
1151
}
1152
 
1152
 
1153
        /* Set variable definition to a file. */
1153
      /* Set variable definition to a file. */
1154
void setdef(char *fname, char *name)
1154
void setdef(char *fname, char *name)
1155
{
1155
{
1156
    char buf[MAX_LINELEN+1];
1156
    char buf[MAX_LINELEN+1];
1157
    char *p1, *p2, *p3;
1157
    char *p1, *p2, *p3;
1158
 
1158
 
1159
    _setdef_changed=0;
1159
    _setdef_changed=0;
1160
    if(strchr(name,'=')==NULL) return;
1160
    if(strchr(name,'=')==NULL) return;
1161
    for(p1=name;*p1;p1++) {
1161
    for(p1=name;*p1;p1++) {
1162
        if(isspace(*p1) && *p1!=' ' && *p1!='\n') *p1=' ';
1162
      if(isspace(*p1) && *p1!=' ' && *p1!='\n') *p1=' ';
1163
        if(*p1==' ') {
1163
      if(*p1==' ') {
1164
            for(p2=p1+1; isspace(*p2) && *p2!='\n'; p2++);
1164
          for(p2=p1+1; isspace(*p2) && *p2!='\n'; p2++);
1165
            if(p2>p1+1) ovlstrcpy(p1+1,p2);
1165
          if(p2>p1+1) ovlstrcpy(p1+1,p2);
1166
            p2=p1+1; if(*p2=='=' || *p2=='\n') ovlstrcpy(p1,p2);
1166
          p2=p1+1; if(*p2=='=' || *p2=='\n') ovlstrcpy(p1,p2);
1167
        }
1167
      }
1168
    }
1168
    }
1169
    if(readfile(fname,buf,sizeof(buf))==NULL) buf[0]=0;
1169
    if(readfile(fname,buf,sizeof(buf))==NULL) buf[0]=0;
1170
    for(p1=find_word_start(name); p1!=NULL; p1=p2) {
1170
    for(p1=find_word_start(name); p1!=NULL; p1=p2) {
1171
        p2=strchr(p1,'\n'); if(p2!=NULL) *p2++=0;
1171
      p2=strchr(p1,'\n'); if(p2!=NULL) *p2++=0;
1172
        p1=find_word_start(p1);
1172
      p1=find_word_start(p1);
1173
        p3=strchr(p1,'='); if(p3==NULL) continue;
1173
      p3=strchr(p1,'='); if(p3==NULL) continue;
1174
        *p3++=0; p3=find_word_start(p3);
1174
      *p3++=0; p3=find_word_start(p3);
1175
        _setdef(buf,p1,p3);
1175
      _setdef(buf,p1,p3);
1176
    }
1176
    }
1177
    if(_setdef_changed) accessfile(buf,"w","%s",fname);
1177
    if(_setdef_changed) accessfile(buf,"w","%s",fname);
1178
}
1178
}
1179
 
1179
 
1180
        /* check whether connecting host is part of given list.
1180
      /* check whether connecting host is part of given list.
1181
         * Returns 0 if no, 1 if yes. */
1181
       * Returns 0 if no, 1 if yes. */
1182
int checkhost(char *hlist)
1182
int checkhost(char *hlist)
1183
{
1183
{
1184
    char buf[MAX_LINELEN+1];
1184
    char buf[MAX_LINELEN+1];
1185
    char lbuf[1024], hbuf1[256], hbuf2[256];
1185
    char lbuf[1024], hbuf1[256], hbuf2[256];
1186
    char *p1, *p2, *pb, *pe, *pp;
1186
    char *p1, *p2, *pb, *pe, *pp;
1187
   
1187
   
1188
    if(*remote_addr==0) return 0;
1188
    if(*remote_addr==0) return 0;
1189
    snprintf(hbuf1,sizeof(hbuf1),"+%s+",remote_addr);
1189
    snprintf(hbuf1,sizeof(hbuf1),"+%s+",remote_addr);
1190
    if(*remote_host!=0) {
1190
    if(*remote_host!=0) {
1191
        snprintf(hbuf2,sizeof(hbuf2),"+%s+",remote_host);
1191
      snprintf(hbuf2,sizeof(hbuf2),"+%s+",remote_host);
1192
        for(p1=hbuf2; *p1; p1++) *p1=tolower(*p1);
1192
      for(p1=hbuf2; *p1; p1++) *p1=tolower(*p1);
1193
    }
1193
    }
1194
    else hbuf2[0]=0;
1194
    else hbuf2[0]=0;
1195
    mystrncpy(buf,find_word_start(hlist),sizeof(buf)); strip_trailing_spaces(buf);
1195
    mystrncpy(buf,find_word_start(hlist),sizeof(buf)); strip_trailing_spaces(buf);
1196
    for(p1=buf; *p1; p1++) {
1196
    for(p1=buf; *p1; p1++) {
1197
        *p1=tolower(*p1);
1197
      *p1=tolower(*p1);
1198
        if(!myisalnum(*p1) && strchr(".-_",*p1)==NULL) *p1=' ';
1198
      if(!myisalnum(*p1) && strchr(".-_",*p1)==NULL) *p1=' ';
1199
    }
1199
    }
1200
    if(strcmp(buf,"all")==0) return 1;  /* all is all */
1200
    if(strcmp(buf,"all")==0) return 1;      /* all is all */
1201
    for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) {
1201
    for(p1=find_word_start(buf); *p1; p1=find_word_start(p2)) {
1202
        p2=find_word_end(p1); if(*p2) *p2++=0;
1202
      p2=find_word_end(p1); if(*p2) *p2++=0;
1203
        if(p2-p1<3) continue;
1203
      if(p2-p1<3) continue;
1204
        if(myisalnum(*p1)) pb="+"; else pb="";
1204
      if(myisalnum(*p1)) pb="+"; else pb="";
1205
        if(myisalnum(*(p2-1))) pe="+"; else pe="";
1205
      if(myisalnum(*(p2-1))) pe="+"; else pe="";
1206
        snprintf(lbuf,sizeof(lbuf),"%s%s%s",pb,p1,pe);
1206
      snprintf(lbuf,sizeof(lbuf),"%s%s%s",pb,p1,pe);
1207
        for(pp=p1; *pp && (myisdigit(*pp) || *pp=='.'); pp++);
1207
      for(pp=p1; *pp && (myisdigit(*pp) || *pp=='.'); pp++);
1208
        if(*pp) pp=hbuf2;       /* host name */
1208
      if(*pp) pp=hbuf2;      /* host name */
1209
        else pp=hbuf1;          /* ip number */
1209
      else pp=hbuf1;         /* ip number */
1210
        if(strstr(pp,lbuf)!=NULL) return 1;     /* found */
1210
      if(strstr(pp,lbuf)!=NULL) return 1;      /* found */
1211
    }
1211
    }
1212
    return 0;
1212
    return 0;
1213
}
1213
}
1214
 
1214
 
1215
        /* return 1 if a word of bf2 is a substring of host.
1215
      /* return 1 if a word of bf2 is a substring of host.
1216
         * Like checkhost, but with time check.
1216
       * Like checkhost, but with time check.
1217
         * The content of bf2[] is destroyed. */
1217
       * The content of bf2[] is destroyed. */
1218
int checkhostt(char bf2[])
1218
int checkhostt(char bf2[])
1219
{
1219
{
1220
    char *p1, *p2, *p3;
1220
    char *p1, *p2, *p3;
1221
        /* compare with starting time */
1221
      /* compare with starting time */
1222
    for(p1=strchr(bf2,'>'); p1!=NULL; p1=strchr(p1+1,'>')) {
1222
    for(p1=strchr(bf2,'>'); p1!=NULL; p1=strchr(p1+1,'>')) {
1223
        if(p1>bf2 && !isspace(*(p1-1))) continue;
1223
      if(p1>bf2 && !isspace(*(p1-1))) continue;
1224
        p3=find_word_start(++p1); p2=find_word_end(p3);
1224
      p3=find_word_start(++p1); p2=find_word_end(p3);
1225
        if(p2-p3!=14) continue;
1225
      if(p2-p3!=14) continue;
1226
        p3[8]='.'; p3[11]=':'; if(*p2) *p2++=0;
1226
      p3[8]='.'; p3[11]=':'; if(*p2) *p2++=0;
1227
        if(strncmp(nowstr,p3,14)<0) return 0;
1227
      if(strncmp(nowstr,p3,14)<0) return 0;
1228
        ovlstrcpy(p1-1,p2); p1-=2;
1228
      ovlstrcpy(p1-1,p2); p1-=2;
1229
    }
1229
    }
1230
        /* compare with ending time */
1230
      /* compare with ending time */
1231
    for(p1=strchr(bf2,'<'); p1!=NULL; p1=strchr(p1+1,'<')) {
1231
    for(p1=strchr(bf2,'<'); p1!=NULL; p1=strchr(p1+1,'<')) {
1232
        if(p1>bf2 && !isspace(*(p1-1))) continue;
1232
      if(p1>bf2 && !isspace(*(p1-1))) continue;
1233
        p3=find_word_start(++p1); p2=find_word_end(p3);
1233
      p3=find_word_start(++p1); p2=find_word_end(p3);
1234
        if(p2-p3!=14) continue;
1234
      if(p2-p3!=14) continue;
1235
        p3[8]='.'; p3[11]=':'; if(*p2) *p2++=0;
1235
      p3[8]='.'; p3[11]=':'; if(*p2) *p2++=0;
1236
        if(strncmp(nowstr,p3,14)>0) return 0;
1236
      if(strncmp(nowstr,p3,14)>0) return 0;
1237
        ovlstrcpy(p1-1,p2); p1-=2;
1237
      ovlstrcpy(p1-1,p2); p1-=2;
1238
    }
1238
    }
1239
    p1=find_word_start(bf2); if(*p1==0) return 1;
1239
    p1=find_word_start(bf2); if(*p1==0) return 1;
1240
    return checkhost(p1);
1240
    return checkhost(p1);
1241
}
1241
}
1242
 
1242
 
1243
        /* bad identification */
1243
      /* bad identification */
1244
void bad_ident(void)
1244
void bad_ident(void)
1245
{
1245
{
1246
    if(cookiegot[0]!=0) {
1246
    if(cookiegot[0]!=0) {
1247
    }
1247
    }
1248
    user_error("bad_ident");
1248
    user_error("bad_ident");
Line 1257... Line 1257...
1257
    setenv("texgif_outfile",instex_fname,1);
1257
    setenv("texgif_outfile",instex_fname,1);
1258
    unsetenv("w_instex_color");
1258
    unsetenv("w_instex_color");
1259
    getwimstexsize=0; fix_tex_size(); getwimstexsize=1;
1259
    getwimstexsize=0; fix_tex_size(); getwimstexsize=1;
1260
    for(p=instex_fname;*p;p++) if(*p=='\n') *p=' ';
1260
    for(p=instex_fname;*p;p++) if(*p=='\n') *p=' ';
1261
    wrapexec=0; call_ssh("%s/%s >%s/ins.Out 2>%s/ins.Err",
1261
    wrapexec=0; call_ssh("%s/%s >%s/ins.Out 2>%s/ins.Err",
1262
                         bin_dir,instex_processor,
1262
                   bin_dir,instex_processor,
1263
                         tmp_dir,tmp_dir);
1263
                   tmp_dir,tmp_dir);
1264
    call_ssh("mv %s %s >/dev/null 2>/dev/null", instex_fname,s2_prefix);
1264
    call_ssh("mv %s %s >/dev/null 2>/dev/null", instex_fname,s2_prefix);
1265
    instex_src[0]=instex_fname[0]=0; instex_cnt=0;
1265
    instex_src[0]=instex_fname[0]=0; instex_cnt=0;
1266
}
1266
}
1267
 
1267
 
1268
        /* put last.phtml */
1268
      /* put last.phtml */
1269
void putlastout(void)
1269
void putlastout(void)
1270
{
1270
{
1271
    int t;
1271
    int t;
1272
    if(instex_cnt>0) instex_flush();
1272
    if(instex_cnt>0) instex_flush();
1273
    t=catfile(stdout,"%s/%s",s2_prefix,lastout);
1273
    t=catfile(stdout,"%s/%s",s2_prefix,lastout);
1274
    if(t==0) printf("Content-type: text/plain\r\n\r\n");
1274
    if(t==0) printf("Content-type: text/plain\r\n\r\n");
1275
}
1275
}
1276
 
1276
 
1277
struct sockaddr_un sun;
1277
struct sockaddr_un sun;
1278
 
1278
 
1279
        /* returns >=0 if OK. */
1279
      /* returns >=0 if OK. */
1280
int kerneld(char *p, int bufsize)
1280
int kerneld(char *p, int bufsize)
1281
{
1281
{
1282
    int sock, s, t, t1, l, *ip;
1282
    int sock, s, t, t1, l, *ip;
1283
    struct timeval tv;
1283
    struct timeval tv;
1284
    fd_set rset;
1284
    fd_set rset;
Line 1288... Line 1288...
1288
    if(s) {bad: close(sock); return -1;}
1288
    if(s) {bad: close(sock); return -1;}
1289
    ip=(int *) p;
1289
    ip=(int *) p;
1290
    l=strlen(p+sizeof(int)); *ip=l;
1290
    l=strlen(p+sizeof(int)); *ip=l;
1291
    s=write(sock,p,l+sizeof(int)); if(s!=l+sizeof(int)) goto bad;
1291
    s=write(sock,p,l+sizeof(int)); if(s!=l+sizeof(int)) goto bad;
1292
    for(t=0, l=bufsize-1; t<l+sizeof(int);) {
1292
    for(t=0, l=bufsize-1; t<l+sizeof(int);) {
1293
        tv.tv_sec=2; tv.tv_usec=0;
1293
      tv.tv_sec=2; tv.tv_usec=0;
1294
        FD_ZERO(&rset); FD_SET(sock,&rset);
1294
      FD_ZERO(&rset); FD_SET(sock,&rset);
1295
        if(select(sock+1,&rset,NULL,NULL,&tv)<=0) goto bad;
1295
      if(select(sock+1,&rset,NULL,NULL,&tv)<=0) goto bad;
1296
        t1=read(sock,p+t,l-t);
1296
      t1=read(sock,p+t,l-t);
1297
        if(t1+t<sizeof(int)) goto bad;
1297
      if(t1+t<sizeof(int)) goto bad;
1298
        l=*ip; if(l<=0) goto bad;
1298
      l=*ip; if(l<=0) goto bad;
1299
        if(l>=bufsize-sizeof(int)-4) user_error("cmd_output_too_long");
1299
      if(l>=bufsize-sizeof(int)-4) user_error("cmd_output_too_long");
1300
        t+=t1;
1300
      t+=t1;
1301
    }
1301
    }
1302
    p[l+sizeof(int)]=0;
1302
    p[l+sizeof(int)]=0;
1303
    close(sock);
1303
    close(sock);
1304
    return l+sizeof(int);
1304
    return l+sizeof(int);
1305
}
1305
}
Line 1312... Line 1312...
1312
    if(kerneld(buf,sizeof(buf))<0)
1312
    if(kerneld(buf,sizeof(buf))<0)
1313
      internal_error("Daemon communication error.");
1313
      internal_error("Daemon communication error.");
1314
    p1=find_word_start(buf+sizeof(int));
1314
    p1=find_word_start(buf+sizeof(int));
1315
    p2=find_word_end(p1); if(*p2) *p2++=0;
1315
    p2=find_word_end(p1); if(*p2) *p2++=0;
1316
    if(strcmp(p1,"OK")==0) {
1316
    if(strcmp(p1,"OK")==0) {
1317
        mystrncpy(p,p2,MAX_LINELEN); return;
1317
      mystrncpy(p,p2,MAX_LINELEN); return;
1318
    }
1318
    }
1319
    p1=find_word_start(p2); p2=find_word_end(p1); if(*p2) *p2++=0;
1319
    p1=find_word_start(p2); p2=find_word_end(p1); if(*p2) *p2++=0;
1320
    p2=find_word_start(p2); p3=find_word_end(p2);
1320
    p2=find_word_start(p2); p3=find_word_end(p2);
1321
    if(*p3) {
1321
    if(*p3) {
1322
        *p3++=0; p3=find_word_start(p3); strip_trailing_spaces(p3);
1322
      *p3++=0; p3=find_word_start(p3); strip_trailing_spaces(p3);
1323
        setvar("wims_error_data",p3);
1323
      setvar("wims_error_data",p3);
1324
    }
1324
    }
1325
    switch(*p1) {
1325
    switch(*p1) {
1326
        case '1': user_error(p2);
1326
      case '1': user_error(p2);
1327
        case '2': module_error(p2);
1327
      case '2': module_error(p2);
1328
        case '3':
1328
      case '3':
1329
        default: internal_error(p2);
1329
      default: internal_error(p2);
1330
    }
1330
    }
1331
    *p=0;
1331
    *p=0;
1332
}
1332
}
1333
 
1333