00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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;
00060 char fileName[256];
00061 char confKey[256];
00062
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
00083
00084
00085
00086 method = getenv("REQUEST_METHOD");
00087 query = getenv("QUERY_STRING");
00088 uri = getenv("REQUEST_URI");
00089 if (argc > 1) method = NULL;
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
00102
00103
00104 } else {
00105
00106 i= (query)? strlen (query):0;
00107
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
00122 printf("Content-Type: text/xml\n");
00123 printf("Pragma: no-cache\n\n");
00124 printf("<?xml version=\"1.0\" ?>\n<editconf>\n");
00125
00126
00127
00128
00129
00130
00131
00132 }
00133
00134
00135 unescape (confValue, sizeof(confValue));
00136
00137
00138
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
00157 for (lineEnd=cp;(lineEnd<ep) && !strchr("#\n\r",lineEnd[0]);lineEnd++);
00158 lineEnd[0]=0;
00159
00160
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;
00172 if (cp<lineEnd) {
00173 cp++;
00174 for (;(strchr(" \t",cp[0])) && (cp<lineEnd);cp++);
00175 valueStart=cp;
00176 }
00177 if (confKey[0]) {
00178 if (strncmp(confKey,keyStart, sizeof(confKey))==0) break;
00179 } else if(keyStart[0] && valueStart[0]) {
00180 if (method == NULL) printf ("%s\n",valueStart);
00181 else printf ("<%s>%s</%s>\n",keyStart,valueStart,keyStart);
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 if (!confValue[0]) {
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);
00197 }
00198 } else {
00199 if ((cfile = fopen(fileName, "w"))==NULL) {thisError=-2;}
00200 else {
00201 fwrite(confFileCopy, 1, (lineStart-confFile), cfile);
00202 if (confValue[0]!='#') {
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);
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]){
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;
00243 }
00244
00245 char * paramValue(struct key_value * params, char * skey) {
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 }