Subversion Repositories wimsdev

Rev

Rev 8124 | Rev 8185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. /* line input / output / translation routines
  18.  * and error routines
  19.  */
  20.  
  21. int exec_wait;
  22.  
  23. void accessfile(char *content, char *type, char *s,...);
  24.  
  25. int execredirected(char *cmdf, char *inf, char *outf, char *errf, char *arg[])
  26. {
  27.     pid_t pid;
  28.     int status, t;
  29.  
  30.     fflush(NULL);       /* flush all output streams before forking
  31.                          * otherwise they will be doubled */
  32.     pid=fork(); if(pid==-1) return -1;
  33.     if(!pid) {  /* child */
  34.         char buf[4096]; int k;
  35.         if(inf!=NULL) (void)freopen(inf,"r",stdin);
  36.         if(outf!=NULL) (void)freopen(outf,"w",stdout);
  37.         if(errf!=NULL) (void)freopen(errf,"w",stderr);
  38.                 /* This is to patch LinuxPPC uid wrapping
  39.                  * for scripts */
  40.         t=0; if(strchr(cmdf,'/')) {
  41.             FILE *tf;
  42.             char buf[16];
  43.             tf=fopen(cmdf,"r"); (void)fread(buf,1,10,tf); fclose(tf);
  44.             if(memcmp(buf+1,"ELF",3)!=0) t=1;
  45.         }
  46.         errno=0;
  47.         if(strchr(cmdf,'/')) execve(cmdf,arg,environ);
  48.         else execvp(cmdf,arg);
  49.         snprintf(buf,sizeof(buf),"Failed to execute");
  50.         for(k=0;arg[k];k++) {
  51.             t=strlen(buf);
  52.             snprintf(buf+t,sizeof(buf)-t," %s",arg[k]);
  53.         }
  54.         t=strlen(buf);
  55.         snprintf(buf+t,sizeof(buf)-t,"\n        %s\n",strerror(errno));
  56.         accessfile(buf,"a","%s/exec.fail",tmpd);
  57.         exit(127);
  58.     }
  59.     else {      /* parent */
  60.         status=0;
  61.         if(exec_wait) {
  62.             waitpid(pid,&status,0);
  63.             return WEXITSTATUS(status);
  64.         }
  65.         else {
  66.             exec_wait=1; addfork(pid,0); return 0;
  67.         }
  68.     }
  69. }
  70.  
  71. /* my system(), but with variable parms
  72.  * More secure than system(), and direct fork.
  73.  */
  74. int call_ssh(int wait,char *s,...)
  75. {
  76.     va_list vp;
  77.     char buf[MAX_LINELEN+1];
  78.     char *arg[1024];
  79.     char *inf=NULL, *outf=NULL, *errf=NULL;
  80.     char *cmdf, *p, *p2;
  81.     int i, d;
  82.  
  83.     va_start(vp,s);
  84.     vsnprintf(buf,sizeof(buf),s,vp);
  85.     va_end(vp);
  86.     p=find_word_start(buf); if(*p==0) return 0;
  87.     cmdf=p;
  88.     for(i=0;*p!=0 && i<1000; p=find_word_start(p2)) {
  89.         switch(*p) {
  90.             case '\'': {
  91.                 p++; p2=strchr(p,'\''); if(p2==NULL) p2=p+strlen(p);
  92.                 d=0; break;
  93.             }
  94.             case '"': {
  95.                 p++; p2=strchr(p,'"'); if(p2==NULL) p2=p+strlen(p);
  96.                 d=0; break;
  97.             }
  98.             default: d=1; p2=find_word_end(p); break;
  99.         }
  100.         if(*p2) *p2++=0;
  101.         if(!d) {arg[i++]=p; continue;}
  102.         switch(*p) {
  103.             case '<': inf=++p; break;
  104.             case '>': {
  105.                 p++; if(*p=='&') {
  106.                     merge: p++; errf=outf=p; break;
  107.                 }
  108.                 else outf=p;
  109.                 break;
  110.             }
  111.             case '&': {
  112.                 p++; if(*p=='>') goto merge;
  113.                 else break;
  114.             }
  115.             case '2': {
  116.                 if(*(p+1)=='>') {errf=p+2; break;}
  117.             }
  118.             default: arg[i++]=p; break;
  119.         }
  120.     }
  121.     arg[i]=NULL;
  122.     exec_wait=wait;
  123.     return execredirected(cmdf,inf,outf,errf,arg);
  124. }
  125.  
  126. /* Read/write to a file with variable parms to print filename */
  127. void accessfile(char *content, char *type, char *s,...)
  128. {
  129.     va_list vp;
  130.     char buf[MAX_LINELEN+1];
  131.     FILE *f;
  132.     int l;
  133.  
  134.     va_start(vp,s);
  135.     vsnprintf(buf,sizeof(buf),s,vp);
  136.     va_end(vp);
  137.     f=fopen(buf,type); if(f==NULL) {
  138.         if(*type=='r') content[0]=0; return;
  139.     }
  140.     switch(*type) {
  141.         case 'a':
  142.         case 'w': {
  143.             l=strlen(content); fwrite(content,1,l,f); break;
  144.         }
  145.         case 'r': {
  146.             l=fread(content,1,MAX_LINELEN-1,f);
  147.             if(l>0 && l<MAX_LINELEN) content[l]=0;
  148.             else content[0]=0;
  149.             _tolinux(content);
  150.             break;
  151.         }
  152.         default: {
  153.             content[0]=0; break;
  154.         }
  155.     }
  156.     fclose(f);
  157. }
  158.  
  159. /* system(), but with variable parms
  160.  * Uses sh to execute command.
  161.  */
  162. int call_sh(int wait,char *s,...)
  163. {
  164.     va_list vp;
  165.     char buf[MAX_LINELEN+1];
  166.     char *abuf[8];
  167.  
  168.     va_start(vp,s);
  169.     vsnprintf(buf,sizeof(buf),s,vp);
  170.     va_end(vp);
  171.     abuf[0]="sh"; abuf[1]="-c"; abuf[2]=buf; abuf[3]=NULL;
  172.     exec_wait=wait;
  173.     return execredirected(abuf[0],NULL,NULL,NULL,abuf);
  174. }
  175.  
  176. void error(char *msg)
  177. {
  178.     fprintf(stderr,"%s %s\n",nowstr, msg);
  179. }
  180.  
  181. void debug(char *p,...)
  182. {
  183.     char lbuf[MAX_LINELEN+1];
  184.     char *pp;
  185.     va_list vp;
  186.  
  187.     snprintf(lbuf,sizeof(lbuf),"%s: ",nowstr);
  188.     pp=lbuf+strlen(lbuf);
  189.     va_start(vp,p);
  190.     vsnprintf(pp,sizeof(lbuf)-(pp-lbuf),p,vp);
  191.     va_end(vp);
  192.     pp=strchr(lbuf,'\n'); if(pp) *pp=0;
  193.     strip_trailing_spaces(lbuf); strcat(lbuf,"\n");
  194.     accessfile(lbuf,"a",debugfile);
  195. }
  196.  
  197.