Annotation of OpenXM/src/asir-port/cgi/webasir2.c, Revision 1.5
1.5 ! takayama 1: /* $OpenXM: OpenXM/src/asir-port/cgi/webasir2.c,v 1.4 2014/08/31 10:20:33 takayama Exp $
1.1 takayama 2: */
3: /*
1.5 ! takayama 4: -(httpd-asir2.sm1) run webasir2
1.3 takayama 5: >log 2>&1
1.5 ! takayama 6: - Todo, timer(limit, command, message) implement in sm1.
! 7: - Example. webasir2 --asir 'oxMessageBody=1%2B3%3B'
! 8: - Example. webasir2 --asir '3-2'
! 9: - Error handling is not completed. Run src/kan96xx/Doc/httpd-asir2-kill.sh by cron.
1.1 takayama 10: */
11: #include <stdio.h>
1.2 takayama 12: #include <stdlib.h>
1.1 takayama 13: #include <sys/types.h>
1.3 takayama 14: #include <unistd.h>
1.1 takayama 15: #include <sys/socket.h>
16: #include <sys/time.h>
17: #include <netinet/in.h>
18: #include <netdb.h>
19: #include <string.h>
20:
21: #define SIZE 0x10000
1.4 takayama 22: #define MKEY "oxMessageBody="
1.2 takayama 23: char *byteArrayToUrlEncoding(char *s,int size);
1.4 takayama 24: static int cgiHex(int p);
25: char *urlEncodedStringToString(char *s);
1.1 takayama 26:
27: int Debug=1;
1.3 takayama 28: int SetTimer=0;
1.1 takayama 29: int main(int argc,char *argv[]) {
30: int dataPort;
31: struct hostent *servhost;
32: struct sockaddr_in dServer;
33: FILE *fp;
34: char s[1];
35: char fname[SIZE];
1.3 takayama 36: int i,j,c;
1.1 takayama 37: char key[SIZE];
38: char comm[SIZE];
1.4 takayama 39: char asircomm[SIZE];
1.1 takayama 40: int quit;
1.3 takayama 41: char workf[SIZE];
1.1 takayama 42: quit = 0;
1.5 ! takayama 43: asircomm[0] = 0;
1.1 takayama 44: for (i=1; i<argc; i++) {
45: if (strcmp(argv[i],"--quit")==0) quit=1;
1.2 takayama 46: else if (strcmp(argv[i],"--asir")==0) {
47: i++;
1.4 takayama 48: if (i <argc) strcpy(asircomm,argv[i]);
1.2 takayama 49: else { usage(); return(-1); }
1.3 takayama 50: }else if (strcmp(argv[i],"--debug")==0) {
51: i++;
52: if (i <argc) sscanf(argv[i],"%d",&Debug);
53: else { usage(); return(-1); }
54: }else if (strcmp(argv[i],"--settimer")==0) {
55: i++;
56: if (i <argc) sscanf(argv[i],"%d",&SetTimer);
57: else { usage(); return(-1); }
58: } else if (strcmp(argv[i],"--stdin")==0) {
59: asircomm[0] = 0; j=0;
60: while ((c=getchar()) != EOF) {
61: asircomm[j] = c; j++; asircomm[j] = 0;
62: if (j > SIZE-3) {
63: fprintf(stderr,"error, too big input.\n"); return(-1);
64: }
65: }
66: } else {
67: usage(); return(0);
1.2 takayama 68: }
1.1 takayama 69: }
70:
1.3 takayama 71: sprintf(workf,"/tmp/tmp-webasir-%d.txt",(int) getpid());
72: sprintf(comm,"ls /tmp/webasir*.txt >%s",workf);
73: system(comm);
74: fp = fopen(workf,"r");
1.1 takayama 75: if (fp == NULL) {
1.5 ! takayama 76: fprintf(stderr,"Failed ls\n"); return(-1);
1.1 takayama 77: }
78: fgets(fname,SIZE-2,fp);
79: for (i=strlen(fname)-1; i>=0; i--) {
80: if (fname[i] <= ' ') fname[i]=0; else break;
81: }
82: fclose(fp);
83: if (strlen(fname)==0) {
1.5 ! takayama 84: if (Debug) fprintf(stderr,"No webasir2 pid file.\n");
! 85: if (Debug) {fprintf(stderr,"No webasir2 is running. Start server.\n");}
! 86: startServer();
! 87: sleep(5);
! 88: system(comm);
! 89: fp = fopen(workf,"r");
! 90: if (fp == NULL) {
! 91: fprintf(stderr,"Failed to start the server.\n"); return(-1);
! 92: }
! 93: fgets(fname,SIZE-2,fp);
! 94: for (i=strlen(fname)-1; i>=0; i--) {
! 95: if (fname[i] <= ' ') fname[i]=0; else break;
! 96: }
! 97: if (strlen(fname) == 0) {
! 98: fprintf(stderr,"Failed to start the server. No webasir2 pid file.\n"); return(-1);
! 99: }
! 100: fclose(fp);
1.1 takayama 101: }
1.5 ! takayama 102:
1.1 takayama 103: fp = fopen(fname,"r");
104: if (fp == NULL) {
105: fprintf(stderr,"Open error of %s\n",fname); return(-1);
106: }
1.5 ! takayama 107: mylock(fname);
1.1 takayama 108: fgets(key,SIZE-2,fp); sscanf(key,"%d",&dataPort);
109: if (Debug) printf("dataPort=%d\n",dataPort);
110: fgets(key,SIZE-2,fp);
111: for (i=strlen(key)-1; i>=0; i--) {
112: if (key[i] <= ' ') key[i]=0; else break;
113: }
114: if (Debug) printf("key=%s\n",key);
115: fclose(fp);
1.3 takayama 116: sprintf(comm,"rm -f %s",workf);
117: system(comm);
1.1 takayama 118:
119: if ((servhost = gethostbyname("localhost")) == NULL) {
120: fprintf(stderr,"bad server name.\n"); return(-1);
121: }
122:
123: /* Connecting to the data port */
124: bzero((char *)&dServer,sizeof(dServer));
125: dServer.sin_family = AF_INET;
126: dServer.sin_port = htons(dataPort);
127: bcopy(servhost->h_addr,
128: (char *)&dServer.sin_addr,servhost->h_length);
129: if ((dataPort = socket(AF_INET,SOCK_STREAM,0)) <0) {
130: fprintf(stderr,"socket allocation is failed.\n");
131: }
132: if (Debug) fprintf(stderr,"Trying to connect port %d ",ntohs(dServer.sin_port));
133:
134: if (connect(dataPort,(struct sockaddr *)&dServer,sizeof(dServer)) == -1) {
1.3 takayama 135: fprintf(stderr,"error: cannot connect\n");
136: }else{ if (Debug) fprintf(stderr,"Connected\n"); }
1.1 takayama 137:
1.5 ! takayama 138: if ((strlen(asircomm)==0) && (!quit)) {myunlock(fname); outputTop(); return(0); }
! 139:
1.4 takayama 140: /* If the input is MKEY=..., extract ... */
141: if (strncmp(asircomm,MKEY,strlen(MKEY))==0) {
142: strcpy(comm,&(asircomm[strlen(MKEY)]));
143: strcpy(asircomm,comm);
144: strcpy(asircomm,urlEncodedStringToString(asircomm));
145: if (Debug) fprintf(stderr,"oxMessageBody, asircomm=%s\n",asircomm);
146: }
147:
1.3 takayama 148: if (SetTimer) {
149: strcpy(comm,asircomm);
150: for (i=strlen(comm)-1; i>=0; i--) {
151: if ((comm[i] == ';') || (comm[i] <= ' ')) comm[i] = 0;
152: else break;
153: }
154: sprintf(asircomm,"timer(%d,%s,\"error(timeout %d sec)\");",
155: SetTimer,comm,SetTimer);
156: }
1.1 takayama 157: if (quit) {
158: sprintf(comm,"GET /?msg=httpdAsirMeta+quit HTTP/1.1\n\n");
159: write(dataPort,comm,strlen(comm));
160: fflush(NULL);
161: }else{
1.2 takayama 162: sprintf(comm,"GET /?%s=%s;\n\n",key,byteArrayToUrlEncoding(asircomm,strlen(asircomm)));
1.1 takayama 163: write(dataPort,comm,strlen(comm));
164: fflush(NULL);
165: }
166:
167: /* get result */
168: for (i=0; i<SIZE; i++) comm[i]=0;
169: read(dataPort,comm,SIZE-2);
1.5 ! takayama 170: /* remove newline(s) */
! 171: for (i=strlen(comm)-1; i>0; i--) {
! 172: if (comm[i] < ' ') comm[i] = 0;
! 173: else break;
! 174: }
! 175: myunlock(fname);
! 176: outputResult(comm);
1.1 takayama 177: }
178:
1.2 takayama 179: /* from kan96xx/plugin/oxcgi.c */
180: /* . - _ A-Z a-z 0-9
181: space --> +
182: */
183: static int isUrlEncoding3(char s) {
184: if ((s == '.') || (s == '-') || (s == '_')) return(0);
185: if ((s >= 'A') && (s <= 'Z')) return(0);
186: if ((s >= 'a') && (s <= 'z')) return(0);
187: if ((s >= '0') && (s <= '9')) return(0);
188: if (s == ' ') return(0);
189: return(1);
190: }
191:
192: char *byteArrayToUrlEncoding(char *s,int size) {
193: int n,i,j;
194: char *r;
195: n = 0;
196: /* get Size */
197: for (i=0; i<size; i++) {
198: if (isUrlEncoding3((char)s[i])) n += 3;
199: n++;
200: }
201: r = malloc(n+1);
202: if (r == NULL) {fprintf(stderr,"%s\n","No more memory."); return(NULL); }
203: r[0] = 0; r[n] = 0;
204: i = 0; j = 0;
205: while ((j < n) && (i<size)) {
206: if (isUrlEncoding3((char)s[i])) {
207: sprintf(&(r[j]),"%%%02X",s[i]); j += 3;
208: }else{
209: if ((char)s[i] == ' ') r[j]='+';
210: else r[j] = s[i];
211: j++; r[j] = 0;
212: }
213: i++;
214: }
215: return(r);
216: }
217:
218:
1.4 takayama 219: char *urlEncodedStringToString(char *s)
220: {
221: char *ts;
222: char *ts2;
223: int i,j;
224: int p;
225: int vstart, vend;
226: if (s == NULL) return(NULL);
227: vstart = 0; vend = strlen(s)-1;
228: ts = (char *) malloc(strlen(s)+2);
229: if (ts == NULL) ;
230: j = 0; ts[j] = 0;
231: for (i=vstart; i<=vend; i++,j++) {
232: ts[j] = 0;
233: if (s[i] == '+') {
234: ts[j] = ' '; ts[j+1] = 0;
235: }else if (s[i] == '%') {
236: p = cgiHex(s[i+1])*16+cgiHex(s[i+2]);
237: i = i+2;
238: ts[j] = p; ts[j+1] = 0;
239: }else {
240: ts[j] = s[i]; ts[j+1] = 0;
241: }
242: }
243: ts2 = (char *) malloc(j);
244: if (ts2 == NULL) ;
245: for (i=0; i<j; i++) {
246: ts2[i] = ts[i]; ts2[i+1] = 0;
247: }
248: return (ts2);
249: }
250:
251: static int cgiHex(int p) {
252: if (p >= '0' && p <= '9') return (p-'0');
253: if (p >= 'A' && p <= 'F') return (p-'A'+10);
254: if (p >= 'a' && p <= 'f') return (p-'a'+10);
255: if (Debug) fprintf(stderr,"%s\n","Invalid argument to cgiHex.");
256: }
257:
1.5 ! takayama 258: outputTop() {
! 259: printf("Content-Type: text/html\n\n");
! 260: printf("<html><body>\nInput <br> asir-command <br> without semicolon. <br><br>\n");
! 261: printf("<form method=\"POST\"> <input type=submit>\n");
! 262: printf("<textarea name=\"oxMessageBody\" rows=10 cols=\"80\" wrap=\"soft\">\n");
! 263: printf("</textarea>\n</form>\n");
! 264: printf("</body></html>\n");
! 265: }
! 266: outputResult(char *s) {
! 267: printf("Content-Type: text/plain\n\n");
! 268: printf("%s\n",s);
! 269: }
! 270: startServer() {
! 271: char comm[SIZE];
! 272: char *r;
! 273: r = getenv("CGI_ASIR_ALLOW");
! 274: if (r == NULL) {
! 275: setenv("CGI_ASIR_ALLOW","[(quit) (fctr)]",1);
! 276: }
! 277: sprintf(comm,"%s/src/kan96xx/Doc/httpd-asir2.sh >/dev/null 2>&1 &",getenv("OpenXM_HOME"));
! 278: /* sprintf(comm,"echo $CGI_ASIR_ALLOW\n"); security check. */
! 279: system(comm);
! 280: }
! 281: mylock(char *fname) {
! 282: char comm[SIZE];
! 283: sprintf(comm,"mv %s /tmp/lock-webasir-%d.txt",fname,getpid());
! 284: system(comm);
! 285: }
! 286: myunlock(char *fname) {
! 287: char comm[SIZE];
! 288: sprintf(comm,"mv /tmp/lock-webasir-%d.txt %s",getpid(),fname);
! 289: system(comm);
! 290: }
1.2 takayama 291: usage() {
292: fprintf(stderr,"webasir2 [--quit] [--asir command_string]\n");
1.3 takayama 293: fprintf(stderr," [--debug level]\n");
294: fprintf(stderr," [--settimer seconds]\n");
295: fprintf(stderr,"webasir2 --stdin ; command is obtained from the stdin.\n");
1.2 takayama 296: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>