Subversion Repositories wimsdev

Rev

Rev 8185 | Rev 8342 | 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.         accessfile(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 accessfile(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); if(f==NULL) {
  137.         if(*type=='r') content[0]=0; return;
  138.     }
  139.     switch(*type) {
  140.         case 'a':
  141.         case 'w': {
  142.             l=strlen(content); fwrite(content,1,l,f); break;
  143.         }
  144.         case 'r': {
  145.             l=fread(content,1,MAX_LINELEN-1,f);
  146.             if(l>0 && l<MAX_LINELEN) content[l]=0;
  147.             else content[0]=0;
  148.             _tolinux(content);
  149.             break;
  150.         }
  151.         default: {
  152.             content[0]=0; break;
  153.         }
  154.     }
  155.     fclose(f);
  156. }
  157.  
  158. /* system(), but with variable parms
  159.  * Uses sh to execute command.
  160.  */
  161. int call_sh(int wait,char *s,...)
  162. {
  163.     va_list vp;
  164.     char buf[MAX_LINELEN+1];
  165.     char *abuf[8];
  166.  
  167.     va_start(vp,s);
  168.     vsnprintf(buf,sizeof(buf),s,vp);
  169.     va_end(vp);
  170.     abuf[0]="sh"; abuf[1]="-c"; abuf[2]=buf; abuf[3]=NULL;
  171.     exec_wait=wait;
  172.     return execredirected(abuf[0],NULL,NULL,NULL,abuf);
  173. }
  174.  
  175. void wimslogd_error(char *msg)
  176. {
  177.     fprintf(stderr,"%s %s\n",nowstr, msg);
  178. }
  179.  
  180. void debug(char *p,...)
  181. {
  182.     char lbuf[MAX_LINELEN+1];
  183.     char *pp;
  184.     va_list vp;
  185.  
  186.     snprintf(lbuf,sizeof(lbuf),"%s: ",nowstr);
  187.     pp=lbuf+strlen(lbuf);
  188.     va_start(vp,p);
  189.     vsnprintf(pp,sizeof(lbuf)-(pp-lbuf),p,vp);
  190.     va_end(vp);
  191.     pp=strchr(lbuf,'\n'); if(pp) *pp=0;
  192.     strip_trailing_spaces(lbuf); strcat(lbuf,"\n");
  193.     accessfile(lbuf,"a",debugfile);
  194. }
  195.  
  196.