1 /* 2 tcpcgi.cgi.c -- HTTP/CGI portion of rutil_tcpcgi. 3 Copyright (C) 2003 Roy Keene 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 email: tcpcgi@rkeene.org 20 21 */ 22 23 /* 24 * tcpcgi.cgi.c -- CGI part of reverse-utils::TCP-over-HTTP/CGI: 25 * This simply needs to relay everything receieved to the daemon 26 * and relay responses to the connected client (stdout). 27 * It should convert the read values before passing them along, however. 28 * -- Roy Keene [300820030944] <tcpcgi@rkeene.org> 29 */ 30 31 #include <sys/time.h> 32 #include <sys/poll.h> 33 #include <sys/wait.h> 34 #include <unistd.h> 35 #include <string.h> 36 #include <stdlib.h> 37 #include <signal.h> 38 #include <stdio.h> 39 #include <fcntl.h> 40 #include <ctype.h> 41 42 #include "tcpcgi.h" 43 #ifndef TCPCGID_STANDALONE 44 #include "tcpcgid.h" 45 #endif 46 #include "tcpnet.h" 47 #define CACHE_DEBUG 48 #include "cache.h" 49 50 char *tcpcgi_strsep(char **stringp, const char *delim) { 51 char *ret = *stringp; 52 if (ret == NULL) return(NULL); /* grrr */ 53 if ((*stringp = strpbrk(*stringp, delim)) != NULL) { 54 *((*stringp)++) = '\0'; 55 } 56 return(ret); 57 } 58 59 void *dehexcode(unsigned char *text, int *len) { 60 int hexabet_r[]={0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15}; 61 unsigned char *textcp; 62 int hex[3]={0,0,0}, hexval; 63 int srcpos,destpos=0; 64 int tl=strlen(text); 65 66 textcp=malloc(strlen(text)+1); 67 for (srcpos=0; srcpos<tl; srcpos++) { 68 if (text[srcpos]=='#') { 69 srcpos++; 70 hex[0]=toupper(text[srcpos])-'0'; 71 hex[1]=toupper(text[srcpos+1])-'0'; 72 if (hex[0]<0 || hex[0]>=(sizeof(hexabet_r)/sizeof(int)) || hex[1]<0 || hex[1]>=(sizeof(hexabet_r)/sizeof(int))) return(NULL); 73 hexval=hexabet_r[hex[0]]<<4; 74 hexval|=hexabet_r[hex[1]]; 75 textcp[destpos++]=hexval; 76 srcpos++; 77 } else if (text[srcpos]=='+') { 78 textcp[destpos++]=' '; 79 } else { 80 textcp[destpos++]=text[srcpos]; 81 } 82 } 83 textcp[destpos]='\0'; 84 85 *len=destpos; 86 return(textcp); 87 } 88 89 int main(int argc, char **argv) { 90 unsigned char retbuflenpt; 91 unsigned int retbuflen; 92 unsigned int qssize, msg_val_len=0, msg_name_len=0; 93 char *qs, *qs_s, *cl, *tok_name, *tok_val; 94 char *msg_name, *msg_val; 95 char retbuf[65535]; 96 FILE *fp; 97 int qslen; 98 int fd; 99 int expectreply=0; 100 101 printf("Content-type: application/octet-stream\n\n"); 102 fflush(stdout); 103 104 fd=createconnection_tcp("localhost", TCPCGI_DAEMON_PORT); 105 if (fd<0) { 106 #ifdef TCPCGID_STANDALONE 107 system("tcpcgid &"); 108 #else 109 tcpcgid_main(); 110 #endif 111 sleep(1); 112 fd=createconnection_tcp("localhost", TCPCGI_DAEMON_PORT); 113 } 114 if (fd<0) { 115 PERROR("createconnection_tcp"); 116 printf("stat: ERROR: Could not create socket.\n"); 117 printf("%c%c", 0, 0); 118 return(0); 119 } 120 fp=fdopen(fd, "r+"); 121 cl=getenv("CONTENT_LENGTH"); 122 123 if (!cl) { 124 qs=getenv("QUERY_STRING"); 125 if (qs) { 126 qs_s=qs=strdup(qs); 127 } else { 128 qs_s=NULL; 129 qs=""; 130 } 131 } else { 132 PRINTERR("Content-length is %s", cl); 133 qslen=atoi(cl); 134 if (qslen<=0) { 135 printf("stat: ERROR: internal error.\n"); 136 printf("%c%c", 0, 0); 137 return(-1); 138 } 139 qs_s=qs=malloc(qssize=qslen); 140 if (!qs) { 141 PERROR("malloc"); 142 printf("stat: ERROR: internal error.\n"); 143 printf("%c%c", 0, 0); 144 return(-1); 145 } 146 PRINTERR("calling read(%i, %p, %i)...", STDIN_FILENO, qs, qslen); 147 qslen=read(STDIN_FILENO, qs, qslen); 148 PRINTERR("Done with read(), got %i.", qslen); 149 if (qslen<0) { 150 qs[0]='\0'; 151 qslen=0; 152 } 153 if (qslen>0) { 154 if (qs[qslen-1]=='\n') qs[qslen-1]='\0'; 155 } 156 #ifdef PARANOID 157 qs=realloc(qs, qslen); 158 #endif 159 } 160 161 while ((tok_name=tcpcgi_strsep(&qs, "&="))!=NULL) { 162 tok_val=tcpcgi_strsep(&qs, "&="); 163 if (tok_val==NULL) break; 164 msg_name=dehexcode(tok_name, &msg_name_len); 165 msg_val=dehexcode(tok_val, &msg_val_len); 166 if (msg_name==NULL || msg_val==NULL) { 167 printf("stat: ERROR: Unable to decode arguments.\n"); 168 printf("%c%c", 0, 0); 169 return(0); 170 } 171 fprintf(fp, "%c%c%c", msg_name_len, (msg_val_len>>8)&0xff, msg_val_len&0xff); 172 fwrite(msg_name, msg_name_len, 1, fp); 173 fwrite(msg_val, msg_val_len, 1, fp); 174 expectreply=1; 175 } 176 fflush(fp); 177 178 if (!expectreply) { 179 printf("stat: ERROR: Nothing to do\n"); 180 printf("%c%c", 0, 0); 181 if (qs_s) free(qs_s); 182 return(0); 183 } 184 185 fgets(retbuf, sizeof(retbuf), fp); 186 while (retbuf[strlen(retbuf)-1]<' ') retbuf[strlen(retbuf)-1]='\0'; 187 printf("stat: %s\n", retbuf); 188 fread(&retbuflenpt, sizeof(retbuflenpt), 1, fp); 189 retbuflen=retbuflenpt<<8; 190 fread(&retbuflenpt, sizeof(retbuflenpt), 1, fp); 191 retbuflen|=retbuflenpt; 192 if (retbuflen!=0) { 193 retbuflen=fread(retbuf, 1, retbuflen, fp); 194 } else { 195 retbuf[0]='\0'; 196 } 197 fprintf(stdout, "%c%c", (retbuflen>>8)&0xff, retbuflen&0xff); 198 fwrite(retbuf, 1, retbuflen, stdout); 199 200 if (qs_s) free(qs_s); 201 fclose(fp); 202 return(0); 203 } |