--- /dev/null
+#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