Subversion Repositories wimsdev

Rev

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