Subversion Repositories wimsdev

Rev

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

Rev 8185 Rev 8343
Line 48... Line 48...
48
 
48
 
49
/* These modules can execute private programs.
49
/* These modules can execute private programs.
50
 * adm/ modules are always trusted, so need no definition here.
50
 * adm/ modules are always trusted, so need no definition here.
51
 */
51
 */
52
char *trusted_modules="";
52
char *trusted_modules="";
53
            /* bit 0: module is not trusted.
53
/* bit 0: module is not trusted.
54
             * bit 1: file in wimshome.
54
  * bit 1: file in wimshome.
55
             * bit 2: readdef or file in writable directory.
55
  * bit 2: readdef or file in writable directory.
56
             */
56
  */
57
int untrust=0;  /* non-zero if user detrusts the module. */
57
int untrust=0;  /* non-zero if user detrusts the module. */
58
 
58
 
59
int error_status=0;
59
int error_status=0;
60
char pidbuf[32];
60
char pidbuf[32];
61
 
61
 
62
void delete_pid(void);
62
void delete_pid(void);
63
 
63
 
64
      /* Internal use only */
64
/* Internal use only */
65
void _debug(char *s,...)
65
void _debug(char *s,...)
66
{
66
{
67
    va_list vp;
67
    va_list vp;
68
    char buf[MAX_LINELEN+1];
68
    char buf[MAX_LINELEN+1];
69
 
69
 
Line 73... Line 73...
73
    setvar("debug",buf); module_error("debug");
73
    setvar("debug",buf); module_error("debug");
74
    exit(1);
74
    exit(1);
75
}
75
}
76
 
76
 
77
 
77
 
78
      /* HTTP response header for non-processed CGI interface */
78
/* HTTP response header for non-processed CGI interface */
79
void nph_header(int code)
79
void nph_header(int code)
80
{
80
{
81
    char *cstr;
81
    char *cstr;
82
    switch(code) {
82
    switch(code) {
83
      case 200: cstr="OK"; break;
83
      case 200: cstr="OK"; break;
Line 118... Line 118...
118
    fprintf(stderr,"wims: %s\n%s\n",msg,strerror(errno));
118
    fprintf(stderr,"wims: %s\n%s\n",msg,strerror(errno));
119
    snprintf(buf,sizeof(buf),"%s: %s\n",nowstr,msg);
119
    snprintf(buf,sizeof(buf),"%s: %s\n",nowstr,msg);
120
    accessfile(buf,"a","%s/internal_error.log",log_dir);
120
    accessfile(buf,"a","%s/internal_error.log",log_dir);
121
}
121
}
122
 
122
 
123
  /* Internal error: panic and forget about requester. */
123
/* Internal error: panic and forget about requester. */
124
void internal_error(char msg[])
124
void internal_error(char msg[])
125
{
125
{
126
    if(error_status<2) {
126
    if(error_status<2) {
127
      nph_header(500);
127
      nph_header(500);
128
      printf("Cache-Control: no-cache\nPragma: no-cache\r\n\
128
      printf("Cache-Control: no-cache\nPragma: no-cache\r\n\
Line 156... Line 156...
156
    module_error("file_name_too_long");
156
    module_error("file_name_too_long");
157
}
157
}
158
 
158
 
159
off_t ftest_size;
159
off_t ftest_size;
160
 
160
 
161
      /* A simple front-end of stat(). */
161
/* A simple front-end of stat(). */
162
int ftest(char *fname)
162
int ftest(char *fname)
163
{
163
{
164
    if(strcmp(fname,lastftest)==0) return lastftype;
164
    if(strcmp(fname,lastftest)==0) return lastftype;
165
/* if(fname[0]=='/' || fname[0]=='.') fprintf(stderr,"ftest: %s\n",fname); */
165
/* if(fname[0]=='/' || fname[0]=='.') fprintf(stderr,"ftest: %s\n",fname); */
166
    mystrncpy(lastftest,fname,sizeof(lastftest));
166
    mystrncpy(lastftest,fname,sizeof(lastftest));
Line 176... Line 176...
176
    return lastftype=is_unknown;
176
    return lastftype=is_unknown;
177
}
177
}
178
 
178
 
179
char fnbuf[MAX_FNAME+1];
179
char fnbuf[MAX_FNAME+1];
180
 
180
 
181
      /* make a filename and check length */
181
/* make a filename and check length */
182
char *mkfname(char buf[], char *s,...)
182
char *mkfname(char buf[], char *s,...)
183
{
183
{
184
    va_list vp;
184
    va_list vp;
185
    char *p;
185
    char *p;
186
 
186
 
Line 198... Line 198...
198
    struct stat st;
198
    struct stat st;
199
    mkfname(buf,"%s/%s",sysmask_trigger_dir,s);
199
    mkfname(buf,"%s/%s",sysmask_trigger_dir,s);
200
    stat(buf,&st);
200
    stat(buf,&st);
201
}
201
}
202
 
202
 
203
      /* read-in a file into buffer. Use open() and read().
203
/* read-in a file into buffer. Use open() and read().
204
       * Return buffer address which will be malloc'ed if buf=NULL. */
204
       * Return buffer address which will be malloc'ed if buf=NULL. */
205
char *readfile(char *fname, char buf[], long int buflen)
205
char *readfile(char *fname, char buf[], long int buflen)
206
{
206
{
207
    int fd, t, st;
207
    int fd, t, st;
208
    long int l, lc;
208
    long int l, lc;
Line 230... Line 230...
230
    if(lc<0 || lc>l || (lc!=l && t==0))
230
    if(lc<0 || lc>l || (lc!=l && t==0))
231
      {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
231
      {if(buf==NULL) free(bf); else buf[0]=0; return NULL;}
232
    bf[lc]=0; _tolinux(bf); return bf;
232
    bf[lc]=0; _tolinux(bf); return bf;
233
}
233
}
234
 
234
 
235
      /* Get a line in a stored working file.
235
/* Get a line in a stored working file.
236
       * Buffer length is always MAX_LINELEN. */
236
       * Buffer length is always MAX_LINELEN. */
237
int wgetline(char buf[], size_t buflen, WORKING_FILE *f)
237
int wgetline(char buf[], size_t buflen, WORKING_FILE *f)
238
{
238
{
239
    int i,j; unsigned int n;
239
    int i,j; unsigned int n;
240
    i=f->linepointer; buf[0]=0;
240
    i=f->linepointer; buf[0]=0;
Line 260... Line 260...
260
      }
260
      }
261
    }
261
    }
262
    return -1;
262
    return -1;
263
}
263
}
264
 
264
 
265
      /* Open a work file. Returns 0 if OK. */
265
/* Open a work file. Returns 0 if OK. */
266
int open_working_file(WORKING_FILE *f, char *fname)
266
int open_working_file(WORKING_FILE *f, char *fname)
267
{
267
{
268
    char *p, *q;
268
    char *p, *q;
269
    void *vp;
269
    void *vp;
270
    int i,j,k,laststart,lc[LINE_LIMIT];
270
    int i,j,k,laststart,lc[LINE_LIMIT];
Line 322... Line 322...
322
    f->lines[i].isstart=1; f->lines[i].llen=0;
322
    f->lines[i].isstart=1; f->lines[i].llen=0;
323
    f->lines[i].address=(f->textbuf)+lc[i];
323
    f->lines[i].address=(f->textbuf)+lc[i];
324
    mfilecnt++; return 0;
324
    mfilecnt++; return 0;
325
}
325
}
326
 
326
 
327
      /* close an earlier opened working file */
327
/* close an earlier opened working file */
328
void close_working_file(WORKING_FILE *f, int cache)
328
void close_working_file(WORKING_FILE *f, int cache)
329
{
329
{
330
    f->linepointer=f->l=0;
330
    f->linepointer=f->l=0;
331
    if(cache && untrust==0 && mcachecnt<MAX_MCACHE && (f->nocache&7)==0) {
331
    if(cache && untrust==0 && mcachecnt<MAX_MCACHE && (f->nocache&7)==0) {
332
      memmove(mcache+mcachecnt,f,sizeof(WORKING_FILE));
332
      memmove(mcache+mcachecnt,f,sizeof(WORKING_FILE));
Line 356... Line 356...
356
    nph_header(420);
356
    nph_header(420);
357
    printf("\r\n\r\nWIMS error processing aborted on nested error.\r\n\r\n%s\r\n",msg);
357
    printf("\r\n\r\nWIMS error processing aborted on nested error.\r\n\r\n%s\r\n",msg);
358
    delete_pid(); exit(1);
358
    delete_pid(); exit(1);
359
}
359
}
360
 
360
 
361
      /* Send an error message to requester and exit.
361
/* Send an error message to requester and exit.
362
       * This is for user errors, language-sensitive. */
362
 * This is for user errors, language-sensitive.
-
 
363
 */
363
void user_error(char msg[])
364
void user_error(char msg[])
364
{
365
{
365
    char erfname[MAX_FNAME+1];
366
    char erfname[MAX_FNAME+1];
366
 
367
 
367
    if(error_status) nested_error(msg);
368
    if(error_status) nested_error(msg);
Line 384... Line 385...
384
    flushoutput(); exit(0);
385
    flushoutput(); exit(0);
385
}
386
}
386
 
387
 
387
void module_error_log(char msg[]);
388
void module_error_log(char msg[]);
388
 
389
 
389
      /* Messages for module errors. English only. */
390
/* Messages for module errors. English only.
390
      /* This is really rudimentary for the time being. */
391
 * This is really rudimentary for the time being.
-
 
392
 */
391
void module_error(char msg[])
393
void module_error(char msg[])
392
{
394
{
393
    int send=0;
395
    int send=0;
394
    char *p;
396
    char *p;
395
    WORKING_FILE mf;
397
    WORKING_FILE mf;
Line 469... Line 471...
469
    vsnprintf(buf,sizeof(buf),s,vp);
471
    vsnprintf(buf,sizeof(buf),s,vp);
470
    va_end(vp);
472
    va_end(vp);
471
    output0(buf);
473
    output0(buf);
472
}
474
}
473
 
475
 
474
     /* read in tmpf in tmp directory, and places in p.
476
/* read in tmpf in tmp directory, and places in p.
475
      * Maximal length: MAX_LINELEN. */
477
 * Maximal length: MAX_LINELEN.
-
 
478
 */
476
void read_tmp_file(char *p, const char *fname)
479
void read_tmp_file(char *p, const char *fname)
477
{
480
{
478
    char *name, *pp;
481
    char *name, *pp;
479
    name=mkfname(NULL,"%s/%s",tmp_dir,fname);
482
    name=mkfname(NULL,"%s/%s",tmp_dir,fname);
480
    if(!exec_is_module || !outputing || !direct_exec
483
    if(!exec_is_module || !outputing || !direct_exec
Line 497... Line 500...
497
      free(s); *p=0;
500
      free(s); *p=0;
498
      chmod(name,S_IRUSR|S_IWUSR);
501
      chmod(name,S_IRUSR|S_IWUSR);
499
    }
502
    }
500
}
503
}
501
 
504
 
502
      /* verify whether the module is trusted.
505
/* verify whether the module is trusted.
503
       * Returns 1 if yes, 0 if no. -1 for error. */
506
 * Returns 1 if yes, 0 if no. -1 for error.
-
 
507
 */
504
int trusted_module(void)
508
int trusted_module(void)
505
{
509
{
506
    char *modname, *w, buf[MAX_LINELEN+1];
510
    char *modname, *w, buf[MAX_LINELEN+1];
507
    int i,n;
511
    int i,n;
508
    static int _trusted=-1;      /* avoid repeated computations */
512
    static int _trusted=-1;      /* avoid repeated computations */
Line 526... Line 530...
526
      if(strcmp(w,modname)==0) goto tr;
530
      if(strcmp(w,modname)==0) goto tr;
527
    }
531
    }
528
    return _trusted=0;
532
    return _trusted=0;
529
}
533
}
530
 
534
 
531
      /* file should be in the module directory, but
535
/* file should be in the module directory, but
532
       * it may also be somewhere else.
536
 * it may also be somewhere else.
533
       * buf[] requires MAX_FNAME+1 length.
537
 * buf[] requires MAX_FNAME+1 length.
534
       * Returns 0 if found. */
538
 * Returns 0 if found.
-
 
539
 */
535
int find_module_file(char *fname, char buf[], int mode)
540
int find_module_file(char *fname, char buf[], int mode)
536
{
541
{
537
    char *p, dtest[32];
542
    char *p, dtest[32];
538
 
543
 
539
    fname=find_word_start(fname);
544
    fname=find_word_start(fname);
540
    if(*fname==0) return -1;
545
    if(*fname==0) return -1;
541
      /* Name checking: no directory backtracing. */
546
/* Name checking: no directory backtracing. */
542
    if(strstr(fname,parent_dir_string)!=NULL) {
547
    if(strstr(fname,parent_dir_string)!=NULL) {
543
      setvar(error_data_string,fname); module_error("illegal_fname");
548
      setvar(error_data_string,fname); module_error("illegal_fname");
544
      return -1;
549
      return -1;
545
    }
550
    }
546
    p=strchr(fname,'/'); if(p==NULL || p>fname+10) goto openit;
551
    p=strchr(fname,'/'); if(p==NULL || p>fname+10) goto openit;
Line 581... Line 586...
581
      }
586
      }
582
    }
587
    }
583
    return 0;
588
    return 0;
584
}
589
}
585
 
590
 
586
      /* check whether a file is user-submitted */
591
/* check whether a file is user-submitted
587
      /* This is deprecated because of the wimshome/ method. */
592
 * This is deprecated because of the wimshome/ method.
-
 
593
 */
588
/* int user_file(char *name) {
594
/* int user_file(char *name) {
589
    if(name[0]=='/' || name[0]=='.' ||
595
    if(name[0]=='/' || name[0]=='.' ||
590
       strstr(name,"classes/")!=NULL ||
596
       strstr(name,"classes/")!=NULL ||
591
       strstr(name,"forums/")!=NULL ||
597
       strstr(name,"forums/")!=NULL ||
592
       strstr(name,"sessions/")!=NULL ||
598
       strstr(name,"sessions/")!=NULL ||
593
       strstr(name,"doc/")!=NULL) return 1; else return 0;
599
       strstr(name,"doc/")!=NULL) return 1; else return 0;
-
 
600
}
594
} */
601
 */
595
 
602
 
596
      /* returns 1 if violation */
603
/* returns 1 if violation */
597
int datafile_check(char *name) {
604
int datafile_check(char *name) {
598
    if((untrust&255)==0) return 0;
605
    if((untrust&255)==0) return 0;
599
    if(strncmp(name,"data/",strlen("data/"))==0) return 0;
606
    if(strncmp(name,"data/",strlen("data/"))==0) return 0;
600
    if(strncmp(name,"authors/",strlen("authors/"))==0) return 0;
607
    if(strncmp(name,"authors/",strlen("authors/"))==0) return 0;
601
    if(strncmp(name,"datamodule/",strlen("datamodule/"))==0) return 0;
608
    if(strncmp(name,"datamodule/",strlen("datamodule/"))==0) return 0;
602
    return 1;
609
    return 1;
603
}
610
}
604
 
611
 
605
      /* returns 0 if success */
612
/* returns 0 if success */
606
void readdatafile(char *name)
613
void readdatafile(char *name)
607
{
614
{
608
    char *pp;
615
    char *pp;
609
    if(strcmp(name,lastdatafile)==0) return;
616
    if(strcmp(name,lastdatafile)==0) return;
610
    lastdata[0]=0; readfile(name,lastdata,WORKFILE_LIMIT);
617
    lastdata[0]=0; readfile(name,lastdata,WORKFILE_LIMIT);
Line 625... Line 632...
625
    pp=strstr(p,tag_string);
632
    pp=strstr(p,tag_string);
626
    if(pp) return pp;
633
    if(pp) return pp;
627
    else return p+strlen(p);
634
    else return p+strlen(p);
628
}
635
}
629
 
636
 
630
      /* datafile structure: number of records.
637
/* datafile structure: number of records.
631
       * tag=1 if direct access */
638
 * tag=1 if direct access
-
 
639
 */
632
unsigned int datafile_recordnum(char *p)
640
unsigned int datafile_recordnum(char *p)
633
{
641
{
634
    char nbuf[MAX_LINELEN+1], *pp;
642
    char nbuf[MAX_LINELEN+1], *pp;
635
    int i, t, ret;
643
    int i, t, ret;
636
 
644
 
Line 648... Line 656...
648
    ret:
656
    ret:
649
    untrust=t;
657
    untrust=t;
650
    return ret;
658
    return ret;
651
}
659
}
652
 
660
 
653
      /* datafile structure: find record n, starting from 1 */
661
/* datafile structure: find record n, starting from 1 */
654
char *datafile_fnd_record(char *p, int n, char bf[])
662
char *datafile_fnd_record(char *p, int n, char bf[])
655
{
663
{
656
    char nbuf[MAX_LINELEN+1], *pp, *p2;
664
    char nbuf[MAX_LINELEN+1], *pp, *p2;
657
    int i, t;
665
    int i, t;
658
 
666
 
Line 703... Line 711...
703
    if(c1>='A') c1=c1-'A'+'9'+1;
711
    if(c1>='A') c1=c1-'A'+'9'+1;
704
    if(c2>='A') c2=c2-'A'+'9'+1;
712
    if(c2>='A') c2=c2-'A'+'9'+1;
705
    return (c1-'0')*16+c2-'0';
713
    return (c1-'0')*16+c2-'0';
706
}
714
}
707
 
715
 
708
      /* Converts back http escaped chars, slight. Does not check buffer length.
716
/* Converts back http escaped chars, slight. Does not check buffer length.
709
       * Returns converted string length. */
717
 * Returns converted string length.
-
 
718
 */
710
int _http2env(char outs[], char ins[])
719
int _http2env(char outs[], char ins[])
711
{
720
{
712
    int j,k,l;
721
    int j,k,l;
713
    l=strlen(ins);
722
    l=strlen(ins);
714
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
723
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
715
      if(isspace(ins[j])) {  /* skip space characters in query string */
724
      if(isspace(ins[j])) {  /* skip space characters in query string */
716
          k--;continue;
725
          k--;continue;
717
      }
726
      }
718
      if(ins[j]=='%') {
727
      if(ins[j]=='%') {
719
            /* skip Carriage-Return. */
728
/* skip Carriage-Return. */
720
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
729
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
721
            j+=2; k--; continue;
730
            j+=2; k--; continue;
722
          }
731
          }
723
          outs[k]=hex2char(ins[j+1],ins[j+2]);
732
          outs[k]=hex2char(ins[j+1],ins[j+2]);
724
          j+=2; continue;
733
          j+=2; continue;
Line 727... Line 736...
727
    }
736
    }
728
    outs[k]=0;
737
    outs[k]=0;
729
    return k;
738
    return k;
730
}
739
}
731
 
740
 
732
      /* Converts back http escaped chars. Does not check buffer length.
741
/* Converts back http escaped chars. Does not check buffer length.
733
       * Returns converted string length. */
742
 * Returns converted string length.
-
 
743
 */
734
int http2env(char outs[], char ins[])
744
int http2env(char outs[], char ins[])
735
{
745
{
736
    int j,k,l;
746
    int j,k,l;
737
    l=strlen(ins);
747
    l=strlen(ins);
738
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
748
    for(j=k=0;j<l && !isspace(ins[j]);j++,k++) {
739
      if(isspace(ins[j])) {  /* skip space characters in query string */
749
      if(isspace(ins[j])) {  /* skip space characters in query string */
740
          k--;continue;
750
          k--;continue;
741
      }
751
      }
742
      if(ins[j]=='%') {
752
      if(ins[j]=='%') {
743
            /* skip Carriage-Return. */
753
/* skip Carriage-Return. */
744
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
754
          if(ins[j+1]=='0' && (ins[j+2]=='d' || ins[j+2]=='D')) {
745
            j+=2; k--; continue;
755
            j+=2; k--; continue;
746
          }
756
          }
747
          outs[k]=hex2char(ins[j+1],ins[j+2]);
757
          outs[k]=hex2char(ins[j+1],ins[j+2]);
748
          j+=2; continue;
758
          j+=2; continue;
Line 757... Line 767...
757
    }
767
    }
758
    outs[k]=0;
768
    outs[k]=0;
759
    return k;
769
    return k;
760
}
770
}
761
 
771
 
762
      /* translate a string to http querystring style.
772
/* translate a string to http querystring style.
763
       * '&' is not translated.
773
 * '&' is not translated.
764
       * Buffer p must be at least MAX_LINELEN. */
774
 * Buffer p must be at least MAX_LINELEN.
-
 
775
 */
765
void tohttpquery(char *p)
776
void tohttpquery(char *p)
766
{
777
{
767
    char trlist[]="     ()[]{}+-*^|/\"\'!:;,<>\n";
778
    char trlist[]="     ()[]{}+-*^|/\"\'!:;,<>\n";
768
    char *pp;
779
    char *pp;
769
    for(pp=p;*pp;pp++) {
780
    for(pp=p;*pp;pp++) {
Line 782... Line 793...
782
          string_modify(p,pp,pp+1,"%%%02X",*pp);pp+=2;
793
          string_modify(p,pp,pp+1,"%%%02X",*pp);pp+=2;
783
      }
794
      }
784
    }
795
    }
785
}
796
}
786
 
797
 
787
      /* substitute backslash parameters. Internal use only. */
798
/* substitute backslash parameters. Internal use only. */
788
void slashsubst(char *p)
799
void slashsubst(char *p)
789
{
800
{
790
    char *p1, *p2, *pt, *pp, namebuf[128];
801
    char *p1, *p2, *pt, *pp, namebuf[128];
791
    int n;
802
    int n;
792
 
803
 
Line 802... Line 813...
802
      }
813
      }
803
      else string_modify(p,p1-1,p1,"$%s",mathfont_prefix);
814
      else string_modify(p,p1-1,p1,"$%s",mathfont_prefix);
804
    }
815
    }
805
}
816
}
806
 
817
 
807
      /* two alarm handlers. */
818
/* two alarm handlers. */
808
void alarm1(int s)
819
void alarm1(int s)
809
{
820
{
810
    if(killpid>0 && kill(killpid,SIGKILL)) module_error("timeup");
821
    if(killpid>0 && kill(killpid,SIGKILL)) module_error("timeup");
811
    killpid=0;
822
    killpid=0;
812
}
823
}
Line 842... Line 853...
842
    if(signal(SIGALRM,alarm1)==SIG_ERR)
853
    if(signal(SIGALRM,alarm1)==SIG_ERR)
843
      internal_error(strerror(errno));
854
      internal_error(strerror(errno));
844
    alarm(limtimex-curr+1);
855
    alarm(limtimex-curr+1);
845
}
856
}
846
 
857
 
847
      /* create pid tag */
858
/* create pid tag */
848
void create_pid(void)
859
void create_pid(void)
849
{
860
{
850
    char buf[MAX_FNAME+1], pbuf[256], obuf[MAX_FNAME+1];
861
    char buf[MAX_FNAME+1], pbuf[256], obuf[MAX_FNAME+1];
851
    struct stat dst;
862
    struct stat dst;
852
    struct utimbuf ub;
863
    struct utimbuf ub;
853
 
864
 
854
    if(robot_access || *session_prefix==0) return;
865
    if(robot_access || *session_prefix==0) return;
855
    if(cmd_type==cmd_getframe) return;
866
    if(cmd_type==cmd_getframe) return;
856
    mkfname(buf,"%s/.pid",s2_prefix);
867
    mkfname(buf,"%s/.pid",s2_prefix);
857
            /* another process running? */
868
/* another process running? */
858
    if(readfile(buf,pbuf,sizeof(pbuf))!=NULL) {
869
    if(readfile(buf,pbuf,sizeof(pbuf))!=NULL) {
859
      mkfname(obuf,"/proc/%s",pbuf);
870
      mkfname(obuf,"/proc/%s",pbuf);
860
      if(stat(obuf,&dst)==0) user_error("double_click");
871
      if(stat(obuf,&dst)==0) user_error("double_click");
861
    }
872
    }
862
    snprintf(pidbuf,sizeof(pidbuf),"%u",getpid());
873
    snprintf(pidbuf,sizeof(pidbuf),"%u",getpid());
863
    accessfile(pidbuf,"w","%s",buf);
874
    accessfile(pidbuf,"w","%s",buf);
864
      /* Touch session time */
875
/* Touch session time */
865
    if(strstr(session_prefix,"sessions/")==NULL) return;
876
    if(strstr(session_prefix,"sessions/")==NULL) return;
866
    ub.actime=ub.modtime=nowtime;
877
    ub.actime=ub.modtime=nowtime;
867
    utime(session_prefix,&ub);
878
    utime(session_prefix,&ub);
868
    if(strchr(session_prefix,'_')!=NULL) { /* touch parent too */
879
    if(strchr(session_prefix,'_')!=NULL) { /* touch parent too */
869
      char sbuf[MAX_FNAME+1], *p;
880
      char sbuf[MAX_FNAME+1], *p;
Line 886... Line 897...
886
      if(errf!=NULL)
897
      if(errf!=NULL)
887
        accessfile("No time left to execute subprograms.\n","w","%s",errf);
898
        accessfile("No time left to execute subprograms.\n","w","%s",errf);
888
      return -100;
899
      return -100;
889
    }
900
    }
890
    lastdatafile[0]=lastftest[0]=0;
901
    lastdatafile[0]=lastftest[0]=0;
891
    fflush(NULL);      /* flush all output streams before forking
902
    fflush(NULL); /* flush all output streams before forking
892
                   * otherwise they will be doubled */
903
                   * otherwise they will be doubled
-
 
904
                   */
893
    pid=fork(); if(pid==-1) return -1;
905
    pid=fork(); if(pid==-1) return -1;
894
    if(!pid) {      /* child */
906
    if(!pid) {      /* child */
895
      char buf[MAX_LINELEN+1]; int k;
907
      char buf[MAX_LINELEN+1]; int k;
896
      (void)nice(10);      /* lower priority for children */
908
      (void)nice(10);      /* lower priority for children */
897
      if(is_multiexec) {
909
      if(is_multiexec) {
Line 902... Line 914...
902
      else {
914
      else {
903
          if(inf!=NULL) (void)freopen(inf,"r",stdin);
915
          if(inf!=NULL) (void)freopen(inf,"r",stdin);
904
          if(outf!=NULL) (void)freopen(outf,"w",stdout);
916
          if(outf!=NULL) (void)freopen(outf,"w",stdout);
905
          if(errf!=NULL) (void)freopen(errf,"w",stderr);
917
          if(errf!=NULL) (void)freopen(errf,"w",stderr);
906
      }
918
      }
907
            /* This is to patch LinuxPPC uid wrapping
919
/* This is to patch LinuxPPC uid wrapping
908
             * for scripts */
920
 * for scripts */
909
      t=0; if(strchr(cmdf,'/')) {
921
      t=0; if(strchr(cmdf,'/')) {
910
          int tf;
922
          int tf;
911
          char tbuf[16];
923
          char tbuf[16];
912
          tf=open(cmdf,O_RDONLY); (void)read(tf,tbuf,8); close(tf);
924
          tf=open(cmdf,O_RDONLY); (void)read(tf,tbuf,8); close(tf);
913
          if(memcmp(tbuf+1,"ELF",3)!=0) t=1;
925
          if(memcmp(tbuf+1,"ELF",3)!=0) t=1;
Line 939... Line 951...
939
      }
951
      }
940
      return WEXITSTATUS(status);
952
      return WEXITSTATUS(status);
941
    }
953
    }
942
}
954
}
943
 
955
 
944
      /* preparation for resident execution.
956
/* preparation for resident execution.
945
       * Returns 1 if already up, otherwise 0. */
957
 * Returns 1 if already up, otherwise 0.
-
 
958
 */
946
int multiexec(char *cmd, char **abuf)
959
int multiexec(char *cmd, char **abuf)
947
{
960
{
948
    char *p;
961
    char *p;
949
    int i;
962
    int i;
950
 
963
 
Line 975... Line 988...
975
    }
988
    }
976
    is_multiexec=0;
989
    is_multiexec=0;
977
    return 1;
990
    return 1;
978
}
991
}
979
 
992
 
980
      /* my system(), but with variable parms
993
/* my system(), but with variable parms
981
       * More secure than system(), and direct fork. */
994
 * More secure than system(), and direct fork.
-
 
995
 */
982
int call_ssh(char *s,...)
996
int call_ssh(char *s,...)
983
{
997
{
984
    va_list vp;
998
    va_list vp;
985
    char buf[MAX_LINELEN+1];
999
    char buf[MAX_LINELEN+1];
986
    char *arg[1024];
1000
    char *arg[1024];
Line 1029... Line 1043...
1029
    }
1043
    }
1030
    arg[i]=NULL;
1044
    arg[i]=NULL;
1031
    return execredirected(cmdf,inf,outf,errf,arg);
1045
    return execredirected(cmdf,inf,outf,errf,arg);
1032
}
1046
}
1033
 
1047
 
1034
      /* Read/write to a file with variable parms to print filename */
1048
/* Read/write to a file with variable parms to print filename */
1035
void accessfile(char *content, char *type, char *s,...)
1049
void accessfile(char *content, char *type, char *s,...)
1036
{
1050
{
1037
    va_list vp;
1051
    va_list vp;
1038
    char buf[MAX_FNAME+1];
1052
    char buf[MAX_FNAME+1];
1039
    int fd;
1053
    int fd;
Line 1053... Line 1067...
1053
    lastdatafile[0]=lastftest[0]=0;
1067
    lastdatafile[0]=lastftest[0]=0;
1054
    if(fd==-1) return;
1068
    if(fd==-1) return;
1055
    (void)write(fd,content,strlen(content)); close(fd);
1069
    (void)write(fd,content,strlen(content)); close(fd);
1056
}
1070
}
1057
 
1071
 
1058
      /* system(), but with variable parms
1072
/* system(), but with variable parms
1059
       * Uses sh to execute command. */
1073
 * Uses sh to execute command.
-
 
1074
 */
1060
int call_sh(char *s,...)
1075
int call_sh(char *s,...)
1061
{
1076
{
1062
    va_list vp;
1077
    va_list vp;
1063
    char buf[MAX_LINELEN+1];
1078
    char buf[MAX_LINELEN+1];
1064
    char *abuf[8];
1079
    char *abuf[8];