Back to index

wims  3.65+svn20090927
lines.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017        /* line input / output / translation routines
00018         * and error routines */
00019 
00020 int exec_wait;
00021 
00022 void accessfile(char *content, char *type, char *s,...);
00023 
00024 int execredirected(char *cmdf, char *inf, char *outf, char *errf, char *arg[])
00025 {
00026     pid_t pid;
00027     int status, t;
00028 
00029     fflush(NULL);    /* flush all output streams before forking
00030                       * otherwise they will be doubled */
00031     pid=fork(); if(pid==-1) return -1;
00032     if(!pid) {       /* child */
00033        char buf[4096]; int k;
00034        if(inf!=NULL) freopen(inf,"r",stdin);
00035        if(outf!=NULL) freopen(outf,"w",stdout);
00036        if(errf!=NULL) freopen(errf,"w",stderr);
00037               /* This is to patch LinuxPPC uid wrapping 
00038                * for scripts */
00039        t=0; if(strchr(cmdf,'/')) {
00040            FILE *tf;
00041            char buf[16];
00042            tf=fopen(cmdf,"r"); fread(buf,1,10,tf); fclose(tf);
00043            if(memcmp(buf+1,"ELF",3)!=0) t=1;
00044        }
00045        errno=0;
00046        if(strchr(cmdf,'/')) execve(cmdf,arg,environ);
00047        else execvp(cmdf,arg);
00048        snprintf(buf,sizeof(buf),"Failed to execute");
00049        for(k=0;arg[k];k++) {
00050            t=strlen(buf);
00051            snprintf(buf+t,sizeof(buf)-t," %s",arg[k]);
00052        }
00053        t=strlen(buf);
00054        snprintf(buf+t,sizeof(buf)-t,"\n   %s\n",strerror(errno));
00055        accessfile(buf,"a","%s/exec.fail",tmpd);
00056        exit(127);
00057     }
00058     else {    /* parent */
00059        status=0;
00060        if(exec_wait) {
00061            waitpid(pid,&status,0);
00062            return WEXITSTATUS(status);
00063        }
00064        else {
00065            exec_wait=1; addfork(pid,0); return 0;
00066        }
00067     }
00068 }
00069 
00070        /* my system(), but with variable parms
00071         * More secure than system(), and direct fork. */
00072 int call_ssh(int wait,char *s,...)
00073 {
00074     va_list vp;
00075     char buf[MAX_LINELEN+1];
00076     char *arg[1024];
00077     char *inf=NULL, *outf=NULL, *errf=NULL;
00078     char *cmdf, *p, *p2;
00079     int i, d;
00080 
00081     va_start(vp,s);
00082     vsnprintf(buf,sizeof(buf),s,vp);
00083     va_end(vp);
00084     p=find_word_start(buf); if(*p==0) return 0;
00085     cmdf=p;
00086     for(i=0;*p!=0 && i<1000; p=find_word_start(p2)) {
00087        switch(*p) {
00088            case '\'': {
00089               p++; p2=strchr(p,'\''); if(p2==NULL) p2=p+strlen(p);
00090               d=0; break;
00091            }
00092            case '"': {
00093               p++; p2=strchr(p,'"'); if(p2==NULL) p2=p+strlen(p);
00094               d=0; break;
00095            }
00096            default: d=1; p2=find_word_end(p); break;
00097        }
00098        if(*p2) *p2++=0;
00099        if(!d) {arg[i++]=p; continue;}
00100        switch(*p) {
00101            case '<': inf=++p; break;
00102            case '>': {
00103               p++; if(*p=='&') {
00104                   merge: p++; errf=outf=p; break;
00105               }
00106               else outf=p;
00107               break;
00108            }
00109            case '&': {
00110               p++; if(*p=='>') goto merge;
00111               else break;
00112            }
00113            case '2': {
00114               if(*(p+1)=='>') {errf=p+2; break;}
00115            }
00116            default: arg[i++]=p; break;
00117        }
00118     }
00119     arg[i]=NULL;
00120     exec_wait=wait;
00121     return execredirected(cmdf,inf,outf,errf,arg);
00122 }
00123 
00124        /* Read/write to a file with variable parms to print filename */
00125 void accessfile(char *content, char *type, char *s,...)
00126 {
00127     va_list vp;
00128     char buf[MAX_LINELEN+1];
00129     FILE *f;
00130     int l;
00131 
00132     va_start(vp,s);
00133     vsnprintf(buf,sizeof(buf),s,vp);
00134     va_end(vp);
00135     f=fopen(buf,type); if(f==NULL) {
00136        if(*type=='r') content[0]=0; return;
00137     }
00138     switch(*type) {
00139        case 'a':
00140        case 'w': {
00141            l=strlen(content); fwrite(content,1,l,f); break;
00142        }
00143        case 'r': {
00144            l=fread(content,1,MAX_LINELEN-1,f);
00145            if(l>0 && l<MAX_LINELEN) content[l]=0;
00146            else content[0]=0;
00147            _tolinux(content);
00148            break;
00149        }
00150        default: {
00151            content[0]=0; break;
00152        }
00153     }
00154     fclose(f);
00155 }
00156 
00157        /* system(), but with variable parms
00158         * Uses sh to execute command. */
00159 int call_sh(int wait,char *s,...)
00160 {
00161     va_list vp;
00162     char buf[MAX_LINELEN+1];
00163     char *abuf[8];
00164 
00165     va_start(vp,s);
00166     vsnprintf(buf,sizeof(buf),s,vp);
00167     va_end(vp);
00168     abuf[0]="sh"; abuf[1]="-c"; abuf[2]=buf; abuf[3]=NULL;
00169     exec_wait=wait;
00170     return execredirected(abuf[0],NULL,NULL,NULL,abuf);
00171 }
00172 
00173 void error(char *msg)
00174 {
00175     fprintf(stderr,"%s %s\n",nowstr, msg);
00176 }
00177 
00178 void debug(char *p,...)
00179 {
00180     char lbuf[MAX_LINELEN+1];
00181     char *pp;
00182     va_list vp;
00183     
00184     snprintf(lbuf,sizeof(lbuf),"%s: ",nowstr);
00185     pp=lbuf+strlen(lbuf);
00186     va_start(vp,p);
00187     vsnprintf(pp,sizeof(lbuf)-(pp-lbuf),p,vp);
00188     va_end(vp);
00189     pp=strchr(lbuf,'\n'); if(pp) *pp=0;
00190     strip_trailing_spaces(lbuf); strcat(lbuf,"\n");
00191     accessfile(lbuf,"a",debugfile);    
00192 }
00193