add CGI to SCGI translator
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 25 Jul 2010 20:19:26 +0000 (20:19 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 25 Jul 2010 20:19:26 +0000 (20:19 +0000)
git-svn-id: https://silmor.de/svn/softmagic/pack/trunk@571 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

cgi2scgi/Makefile [new file with mode: 0644]
cgi2scgi/main.c [new file with mode: 0644]

diff --git a/cgi2scgi/Makefile b/cgi2scgi/Makefile
new file mode 100644 (file)
index 0000000..b961fb7
--- /dev/null
@@ -0,0 +1,7 @@
+CC     = gcc
+CFLAGS = -Wall -g
+
+all: cgi2scgi
+
+cgi2scgi: main.c
+       $(CC) $(CFLAGS) -o $@ $^
diff --git a/cgi2scgi/main.c b/cgi2scgi/main.c
new file mode 100644 (file)
index 0000000..417e4e8
--- /dev/null
@@ -0,0 +1,130 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+extern char**environ;
+
+#define KB *1024
+#define MB KB KB
+
+char buf[1 MB];
+int scfd=-1;
+
+
+#define ERROR "500 CGI Bridge Error\r\n\r\nCGI Bridge not working correctly.\r\n"
+
+void encodeEnviron()
+{
+       char *evc,**evn;
+       char buf2[32];
+       int pos=0;
+       memset(buf,0,sizeof(buf));
+       //encode SCGI
+       strcpy(buf,"SCGI");pos=5;
+       strcpy(buf+pos,"1");pos+=2;
+       //encode content length
+       evc=getenv("CONTENT_LENGTH");
+       memcpy(buf,"CONTENT_LENGTH",15);
+       if(evc){
+               memcpy(buf,evc,strlen(evc)+1);
+               pos+=16+strlen(evc);
+       }else{
+               memcpy(buf,"0",2);
+               pos+=17;
+       }
+       //encode variables
+       evn=environ;
+       while(*evn){
+               int l1,l2;
+               if(strcmp(*evn,"CONTENT_LENGTH")==0)continue;
+               l1=strlen(*evn)+1;
+               evc=getenv(*evn);
+               l2=strlen(evc)+1;
+               if((l1+l2+pos)>sizeof(buf))break;
+               memcpy(buf+pos,*evn,l1);pos+=l1;
+               if(evc){
+                       memcpy(buf+pos,evc,l2);
+                       pos+=l2;
+               }else
+                       pos++;
+               evn++;
+       }
+       sprintf(buf2,"%i:",pos);
+       write(scfd,buf2,strlen(buf2));
+       write(scfd,buf,pos);
+       write(scfd,",",1);
+}
+
+void relayBody()
+{
+       //get content length
+       char*cle,*ep;
+       int cl,l;
+       cle=getenv("CONTENT_LENGTH");
+       if(cle==0)return;
+       cl=strtol(cle,&ep,10);
+       if(*ep!=0)return;
+       while(cl>0){
+               if(cl>sizeof(buf))l=sizeof(buf);else l=cl;
+               l=read(STDIN_FILENO,buf,l);
+               write(scfd,buf,l);
+       }
+}
+
+void relayResponse()
+{
+       fd_set rd,ex;
+       int maxfd=scfd;
+       int rfd;
+       if(STDOUT_FILENO<maxfd)maxfd=STDOUT_FILENO;
+       maxfd++;
+       do{
+               FD_ZERO(&rd);
+               FD_ZERO(&ex);
+               FD_SET(STDOUT_FILENO,&ex);
+               FD_SET(scfd,&ex);
+               FD_SET(scfd,&rd);
+               rfd=select(maxfd,&rd,0,&ex,0);
+               if(rfd<0){
+                       if(errno==EINTR)continue;
+                       return;
+               }
+               if(rfd==0)continue;
+               if(FD_ISSET(scfd,&ex) || FD_ISSET(STDOUT_FILENO,&ex))
+                       return;
+               if(FD_ISSET(scfd,&rd)){
+                       int r;
+                       r=read(scfd,buf,sizeof(buf));
+                       if(r>0)write(STDOUT_FILENO,buf,r);
+                       else return;
+               }
+       }while(1);
+}
+
+
+int main(int argc,char**argv)
+{
+       //open connection
+       if(argc!=2){
+               fprintf(stderr,"Error: usage %s socket\n",*argv);
+               printf(ERROR);
+               return 1;
+       }
+       scfd=open(argv[1],O_RDWR);
+       if(scfd<0){
+               fprintf(stderr,"Error: cannot open socket\n");
+               printf(ERROR);
+               return 1;
+       }
+       //send request
+       encodeEnviron();
+       relayBody();
+       //relay response
+       relayResponse();
+       
+       return 0;
+}
\ No newline at end of file