apps/editconf/editconf.c

Go to the documentation of this file.
00001 /*
00002 ** -----------------------------------------------------------------------------**
00003 ** editconf.c
00004 **
00005 ** Copyright (C) 2006 Elphel, Inc.
00006 **
00007 ** -----------------------------------------------------------------------------**
00008 **  This program is free software: you can redistribute it and/or modify
00009 **  it under the terms of the GNU General Public License as published by
00010 **  the Free Software Foundation, either version 3 of the License, or
00011 **  (at your option) any later version.
00012 **
00013 **  This program is distributed in the hope that it will be useful,
00014 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 **  GNU General Public License for more details.
00017 **
00018 **  You should have received a copy of the GNU General Public License
00019 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 ** -----------------------------------------------------------------------------**
00021 */
00022 
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <unistd.h>
00026 #include <sys/stat.h>
00027 #include <sys/ioctl.h>
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <fcntl.h>
00031 #include <string.h>
00032 
00033  
00034 
00035 #define QRY_MAXPARAMS 64
00036 
00037 char  copyQuery [4096];
00038 const char *uri;
00039 const char *method;
00040 const char *query;
00041 
00042 struct key_value {
00043         char *key;
00044         char *value;
00045 };
00046 
00047 struct key_value gparams[QRY_MAXPARAMS+1];
00048 
00049 int unescape(char *, int);
00050 int hexdigit(char);
00051 char * paramValue(struct key_value *, char *);
00052 int parseQuery(struct key_value *, char *);
00053 
00054 
00055 int main(argc, argv)
00056     int argc;
00057     char *argv[];
00058 {
00059   int i; //,j,k,a,l;
00060   char fileName[256];
00061   char confKey[256];
00062 //  char confSection[256];
00063   char confValue[1024];
00064   char *confFile=NULL;
00065   char *confFileCopy=NULL;
00066   char * v;
00067   int  useEQ=1;
00068   FILE *  cfile;
00069   int  thisError=0;
00070   size_t fileSize;
00071   char * cp;
00072   char * ep;
00073   char * lineEnd;
00074   char * lineStart;
00075   char * keyStart;
00076   char * valueStart;
00077   
00078   
00079   fileName[0]=0;   fileName[sizeof(fileName)-1]=0;
00080   confKey[0]=0;    confKey[sizeof(confKey)-1]=0;
00081   confValue[0]=0;  confValue[sizeof(confValue)-1]=0;
00082 //  short int hsz[2];
00083   
00084 //  struct stat buf;
00085  
00086   method = getenv("REQUEST_METHOD");
00087   query = getenv("QUERY_STRING");
00088   uri = getenv("REQUEST_URI");
00089   if (argc > 1) method = NULL; // to fix a bug when a script is called as CGI and uses editconf as a command line app.
00090   if (method == NULL) {
00091     if (argc<3) {printf("This program should be run as a CGI from the web server or:\n" \
00092                         "editconf filename key         -  will return a key value if any\n" \
00093                         "editconf filename key value   -  will set a value to a key (using '=' as separator)" \
00094                         "editconf filename key value 0 -  will set a value to a key (using ' ' as separator)");
00095                         exit (0);}
00096     strncpy(fileName,argv[1], sizeof(fileName));     
00097     strncpy(confKey, argv[2], sizeof(confKey));
00098     if (argc>3) strncpy(confValue,argv[3], sizeof(confValue));
00099     if (argc>4) useEQ   =atoi(argv[4]);
00100   
00101   /* Not a CGI! */
00102 //     printf("This program should be run as a CGI from the web server!\n");
00103 //     exit(1);
00104   } else {
00105 
00106   i= (query)? strlen (query):0;
00107 //  fprintf(stderr,"querry length=%d\n", i);
00108 
00109   if (i>(sizeof(copyQuery)-1)) i= sizeof(copyQuery)-1;
00110   if (i>0) strncpy(copyQuery,query, i);
00111   copyQuery[i]=0;
00112   unescape(copyQuery,sizeof(copyQuery));
00113 
00114   parseQuery(gparams, copyQuery);
00115 
00116   if((v = paramValue(gparams, "file"))  != NULL) strncpy(fileName,v, sizeof(fileName));
00117   if((v = paramValue(gparams, "key"))   != NULL) strncpy(confKey,v, sizeof(confKey));
00118   if((v = paramValue(gparams, "value")) != NULL) strncpy(confValue,v, sizeof(confValue));
00119   if((v = paramValue(gparams, "eq")) != NULL) useEQ=atoi (v);
00120 
00121 //    int keyFound=0;
00122       printf("Content-Type: text/xml\n");
00123       printf("Pragma: no-cache\n\n"); // 2 new lines!
00124       printf("<?xml version=\"1.0\" ?>\n<editconf>\n");
00125 //      printf("<argc>%d</argc>\n",argc);
00126 /*      
00127    if (fileName[0])  printf("<fileName>%s</fileName>\n",fileName);     
00128    if (confKey[0])   printf("<confKey>%s</confKey>\n",confKey);     
00129    if (confValue[0]) printf("<confValue>%s</confValue>\n",confValue);     
00130                      printf("<useEQ>%d</useEQ>\n",useEQ);     
00131 */                     
00132   } // end of METHOD==NULL/else
00133 
00134 
00135       unescape (confValue, sizeof(confValue));
00136 
00137 
00138 //  printf("<file>%s</file>\n",fileName);     
00139       if ((cfile = fopen(fileName, "r"))==NULL) {thisError=-1;}
00140       else {
00141         fseek(cfile, 0L, SEEK_END);
00142         fileSize=  ftell(cfile);
00143         confFile= (char*) malloc(fileSize+1);
00144         fseek(cfile, 0L, SEEK_SET);
00145         i=fread(confFile, 1, fileSize, cfile);
00146         for (i=0; i<fileSize; i++) if (confFile[i]==0) confFile[i]=' ';
00147         confFileCopy= strdup(confFile);
00148         confFile[fileSize]=0;
00149         fclose (cfile);
00150         ep=confFile+fileSize;
00151         valueStart=ep;
00152         for (lineStart=confFile;(lineStart-confFile)<fileSize; lineStart=ep+1) {
00153           cp=lineStart;
00154           ep=strchr(cp,'\n'); if (!ep) ep=confFile+fileSize;
00155           ep[0]=0;
00156 // now - just output everything as xml          
00157           for (lineEnd=cp;(lineEnd<ep) && !strchr("#\n\r",lineEnd[0]);lineEnd++);
00158           lineEnd[0]=0;
00159 // now the line is truncated by any end of line or "#"          
00160 // still left white spaces before "#"
00161           lineEnd--;
00162           while ((lineEnd>=cp) && strchr(" \t",lineEnd[0])) {
00163             lineEnd[0]=0;
00164             lineEnd--;
00165           }
00166           lineEnd++;
00167           for (;(strchr(" \t",cp[0])) && (cp<lineEnd);cp++);
00168           keyStart=cp;
00169           for (;!(strchr(" \t=",cp[0])) && (cp<lineEnd);cp++);
00170           cp[0]=0;
00171           valueStart=cp; // will point on empty string
00172           if (cp<lineEnd) {
00173             cp++;
00174             for (;(strchr(" \t",cp[0])) && (cp<lineEnd);cp++);
00175             valueStart=cp;
00176           }
00177           if (confKey[0]) { // key specified
00178               if (strncmp(confKey,keyStart, sizeof(confKey))==0) break;
00179           } else if(keyStart[0] && valueStart[0]) { // no jey specified - output all lines
00180           if (method == NULL)  printf ("%s\n",valueStart);        // will never be used
00181           else                 printf ("<%s>%s</%s>\n",keyStart,valueStart,keyStart);
00182           }    
00183         } // end of for (lineStart=confFile;(lineStart-confFile)<fileSize; lineStart=ep+1) // may break;
00184         
00185 //printf ("<fileEnd>%d</fileEnd>\n",fileSize);        
00186 //printf ("<lineStart>%d</lineStart>\n",(lineStart-confFile));        
00187 //printf ("<lineEnd>%d</lineEnd>\n",(lineEnd-confFile));        
00188 //printf ("<keyStart>%d</keyStart>\n",(keyStart-confFile));        
00189 //printf ("<valueStart>%d</valueStart>\n",(keyStart-confFile));
00190         
00191         if (!confValue[0]) { // read value]
00192            if (method == NULL) {
00193              if ((lineStart-confFile)<fileSize)  printf ("%s\n",valueStart);
00194            }else   {
00195               if ((lineStart-confFile)<fileSize)  printf ("<value>%s</value>\n",valueStart);
00196               else if (confKey[0])                printf ("<error>%d</error>\n",-3); // key not found
00197             } 
00198         } else { // modify value
00199           if ((cfile = fopen(fileName, "w"))==NULL) {thisError=-2;}
00200           else { // file opened OK
00201             fwrite(confFileCopy, 1, (lineStart-confFile), cfile); // write everything before the line with a key (if any)
00202             if (confValue[0]!='#') { // replace the key
00203               if ((lineStart>confFile) && (confFileCopy[lineStart-confFile-1] != '\n'))  fprintf(cfile,"\n");
00204               if (useEQ) fprintf(cfile,"%s=%s\n",confKey,confValue);
00205               else       fprintf(cfile,"%s %s\n",confKey,confValue);
00206             }
00207             if ((ep-confFile) < fileSize)  fwrite(confFileCopy+(ep+1-confFile), 1, (confFile+ fileSize - ep-1), cfile); // write everything after the line with a key (if any)
00208           }
00209         }
00210       }
00211       if (method != NULL) {
00212         if ((confValue[0])&& !thisError)  printf("<error>0</error>\n");
00213         if (confFile) free (confFile);
00214         if (confFileCopy) free (confFileCopy);
00215         if (thisError)  printf("<error>%d</error>\n",thisError);
00216         printf("</editconf>\n");
00217       }  
00218   return 0; 
00219 }
00220 
00221 int unescape (char * s, int l) {
00222   int i=0;
00223   int j=0;
00224   while ((i<l) && s[i]) {
00225     if ((s[i]=='%') && (i<(l-2)) && s[i+1]){ // behavior from Mozilla
00226       s[j++]=(hexdigit(s[i+1])<<4) | hexdigit(s[i+2]);
00227       i+=3;
00228     } else s[j++]=s[i++];
00229   }
00230   if (i<l) s[j]=0;
00231   return j;
00232 }
00233 
00234 int hexdigit (char c) {
00235   int i;
00236   i=c-'0';
00237   if ((i>=0) && (i<10)) return i;
00238   i=c-'a'+10;
00239   if ((i>=10) && (i<16)) return i;
00240   i=c-'A'+10;
00241   if ((i>=10) && (i<16)) return i;
00242   return 0; // could be -1??
00243 }
00244 
00245 char * paramValue(struct key_value * params, char * skey) { // returns pointer to parameter value, NULL if not defined
00246   int i=0;
00247   if (skey)
00248    while ((i<QRY_MAXPARAMS) && (params[i].key)) {
00249     if (strcmp(skey,params[i].key)==0) return   params[i].value;
00250 
00251     i++;
00252    }
00253   return NULL;
00254 }
00255 
00256 int parseQuery(struct key_value * params, char * qry) {
00257   char * cp;
00258   int l=0;
00259   cp=strtok(qry,"=");
00260   while ((cp) && (l<QRY_MAXPARAMS)) {
00261     params[l].key=cp;
00262     cp=strtok(NULL,"&");
00263     params[l++].value=cp;
00264     if (cp) cp=strtok(NULL,"=");
00265   }
00266  params[l].key=NULL;
00267  return l;
00268 }

Generated on Fri Nov 28 00:06:21 2008 for elphel by  doxygen 1.5.1