Subversion Repositories wimsdev

Rev

Rev 8849 | Rev 15847 | 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. #include "wimslogd.h"
  21.  
  22. int exec_wait;
  23.  
  24. int execredirected(char *cmdf, char *inf, char *outf, char *errf, char *arg[])
  25. {
  26.     pid_t pid;
  27.     int status, t;
  28.  
  29.     fflush(NULL);      /* flush all output streams before forking
  30.                         * otherwise they will be doubled */
  31.     pid=fork(); if(pid==-1) return -1;
  32.     if(!pid) {      /* child */
  33.       char buf[4096]; int k;
  34.       if(inf!=NULL) (void)freopen(inf,"r",stdin);
  35.       if(outf!=NULL) (void)freopen(outf,"w",stdout);
  36.       if(errf!=NULL) (void)freopen(errf,"w",stderr);
  37.             /* This is to patch LinuxPPC uid wrapping
  38.              * for scripts */
  39.       t=0; if(strchr(cmdf,'/')) {
  40.           FILE *tf;
  41.           char buf[16];
  42.           tf=fopen(cmdf,"r"); (void)fread(buf,1,10,tf); fclose(tf);
  43.           if(memcmp(buf+1,"ELF",3)!=0) t=1;
  44.       }
  45.       errno=0;
  46.       if(strchr(cmdf,'/')) execve(cmdf,arg,environ);
  47.       else execvp(cmdf,arg);
  48.       snprintf(buf,sizeof(buf),"Failed to execute");
  49.       for(k=0;arg[k];k++) {
  50.           t=strlen(buf);
  51.           snprintf(buf+t,sizeof(buf)-t," %s",arg[k]);
  52.       }
  53.       t=strlen(buf);
  54.       snprintf(buf+t,sizeof(buf)-t,"\n  %s\n",strerror(errno));
  55.       wlogdaccessfile(buf,"a","%s/exec.fail",tmpd);
  56.       exit(127);
  57.     }
  58.     else {      /* parent */
  59.       status=0;
  60.       if(exec_wait) {
  61.           waitpid(pid,&status,0);
  62.           return WEXITSTATUS(status);
  63.       }
  64.       else {
  65.           exec_wait=1; addfork(pid,0); return 0;
  66.       }
  67.     }
  68. }
  69.  
  70. /* my system(), but with variable parms
  71.  * More secure than system(), and direct fork.
  72.  */
  73. int call_ssh(int wait,char *s,...)
  74. {
  75.     va_list vp;
  76.     char buf[MAX_LINELEN+1];
  77.     char *arg[1024];
  78.     char *inf=NULL, *outf=NULL, *errf=NULL;
  79.     char *cmdf, *p, *p2;
  80.     int i, d;
  81.  
  82.     va_start(vp,s);
  83.     vsnprintf(buf,sizeof(buf),s,vp);
  84.     va_end(vp);
  85.     p=find_word_start(buf); if(*p==0) return 0;
  86.     cmdf=p;
  87.     for(i=0;*p!=0 && i<1000; p=find_word_start(p2)) {
  88.       switch(*p) {
  89.           case '\'': {
  90.             p++; p2=strchr(p,'\''); if(p2==NULL) p2=p+strlen(p);
  91.             d=0; break;
  92.           }
  93.           case '"': {
  94.             p++; p2=strchr(p,'"'); if(p2==NULL) p2=p+strlen(p);
  95.             d=0; break;
  96.           }
  97.           default: d=1; p2=find_word_end(p); break;
  98.       }
  99.       if(*p2) *p2++=0;
  100.       if(!d) {arg[i++]=p; continue;}
  101.       switch(*p) {
  102.           case '<': inf=++p; break;
  103.           case '>': {
  104.             p++; if(*p=='&') {
  105.                 merge: p++; errf=outf=p; break;
  106.             }
  107.             else outf=p;
  108.             break;
  109.           }
  110.           case '&': {
  111.             p++; if(*p=='>') goto merge;
  112.             else break;
  113.           }
  114.           case '2': {
  115.             if(*(p+1)=='>') {errf=p+2; break;}
  116.           }
  117.           default: arg[i++]=p; break;
  118.       }
  119.     }
  120.     arg[i]=NULL;
  121.     exec_wait=wait;
  122.     return execredirected(cmdf,inf,outf,errf,arg);
  123. }
  124.  
  125. /* Read/write to a file with variable parms to print filename */
  126. void wlogdaccessfile(char *content, char *type, char *s,...)
  127. {
  128.     va_list vp;
  129.     char buf[MAX_LINELEN+1];
  130.     FILE *f;
  131.     int l;
  132.  
  133.     va_start(vp,s);
  134.     vsnprintf(buf,sizeof(buf),s,vp);
  135.     va_end(vp);
  136.     f=fopen(buf,type);
  137.     if(f==NULL) {
  138.       if(*type=='r') content[0]=0;
  139.       return;
  140.     }
  141.     switch(*type) {
  142.       case 'a':
  143.       case 'w': {
  144.           l=strlen(content); fwrite(content,1,l,f); break;
  145.       }
  146.       case 'r': {
  147.           l=fread(content,1,MAX_LINELEN-1,f);
  148.           if(l>0 && l<MAX_LINELEN) content[l]=0;
  149.           else content[0]=0;
  150.           _tolinux(content);
  151.           break;
  152.       }
  153.       default: {
  154.           content[0]=0; break;
  155.       }
  156.     }
  157.     fclose(f);
  158. }
  159.  
  160. /* system(), but with variable parms
  161.  * Uses sh to execute command.
  162.  */
  163. int call_sh(int wait,char *s,...)
  164. {
  165.     va_list vp;
  166.     char buf[MAX_LINELEN+1];
  167.     char *abuf[8];
  168.  
  169.     va_start(vp,s);
  170.     vsnprintf(buf,sizeof(buf),s,vp);
  171.     va_end(vp);
  172.     abuf[0]="sh"; abuf[1]="-c"; abuf[2]=buf; abuf[3]=NULL;
  173.     exec_wait=wait;
  174.     return execredirected(abuf[0],NULL,NULL,NULL,abuf);
  175. }
  176.  
  177. void wimslogd_error(char *msg)
  178. {
  179.     fprintf(stderr,"%s %s\n",nowstr, msg);
  180. }
  181.  
  182. void debug(char *p,...)
  183. {
  184.     char lbuf[MAX_LINELEN+1];
  185.     char *pp;
  186.     va_list vp;
  187.  
  188.     snprintf(lbuf,sizeof(lbuf),"%s: ",nowstr);
  189.     pp=lbuf+strlen(lbuf);
  190.     va_start(vp,p);
  191.     vsnprintf(pp,sizeof(lbuf)-(pp-lbuf),p,vp);
  192.     va_end(vp);
  193.     pp=strchr(lbuf,'\n'); if(pp) *pp=0;
  194.     strip_trailing_spaces(lbuf); strcat(lbuf,"\n");
  195.     wlogdaccessfile(lbuf,"a",debugfile);
  196. }
  197.  
  198.