int PipeCommandProcessorWrite(TProcessingModule *ProcMod, const char *InData, int InLen, char **OutData, int *OutLen, int Flush) { STREAM *S; S=(STREAM *) ProcMod->Data; if (InLen > 0) { STREAMWriteBytes(S,InData,InLen); STREAMFlush(S); } if (Flush) { if (S->out_fd > -1) close(S->out_fd); S->out_fd=-1; } else if (! STREAMCheckForBytes(S)) return(0); return(STREAMReadBytes(S,*OutData,*OutLen)); }
int CheckForKeyboardInput() { char *Tempstr=NULL; int result=FALSE; if (STREAMCheckForBytes(StdIn)) { Tempstr=STREAMReadLine(Tempstr,StdIn); StripTrailingWhitespace(Tempstr); if (StrLen(Tempstr)) { ListAddItem(DownloadQueue,CopyStr(NULL,Tempstr)); if (! (Flags & FLAG_QUIET)) fprintf(stderr,"\r\nQUEUED: %s\n",Tempstr); result=TRUE; } } DestroyString(Tempstr); return(result); }
int ChrootProcessRequest(STREAM *S, HTTPSession *Session, const char *Type, const char *Path, const char *SearchPath) { char *Tempstr=NULL; char *ResponseLine=NULL, *Headers=NULL, *ptr; off_t ContentLength=0; int KeepAlive=FALSE, RetVal=FALSE; LogFileFlushAll(TRUE); if (! ChrootSendRequest(Session, Type, Path, SearchPath)) return(FALSE); //Wait till process outside of chroot responds to our request, while (STREAMCheckForBytes(ParentProcessPipe)==0) usleep(10000); //Read 'OKAY' line Tempstr=STREAMReadLine(Tempstr, ParentProcessPipe); //then send it the post data if there is any. if (strcmp(Session->Method,"POST") ==0) { if (Session->ContentSize > 0) { LogToFile(Settings.LogPath,"PUSH POST: [%d]",Session->ContentSize); STREAMSendFile(S, ParentProcessPipe, Session->ContentSize, SENDFILE_KERNEL|SENDFILE_LOOP); LogToFile(Settings.LogPath,"PUSH POST:DONE [%d]",Session->ContentSize); } //we shouldn't need this CR-LF, as we've sent 'Content-Length' characters //but some CGI implementations seem to expect it, and it does no harm to //provide it anyway STREAMWriteLine("\r\n",ParentProcessPipe); STREAMFlush(ParentProcessPipe); } //Handle Headers from CGI script Headers=CopyStr(Headers,""); ResponseLine=STREAMReadLine(ResponseLine,ParentProcessPipe); StripTrailingWhitespace(ResponseLine); if (StrLen(ResponseLine)) RetVal=TRUE; Tempstr=STREAMReadLine(Tempstr,ParentProcessPipe); while (Tempstr) { StripTrailingWhitespace(Tempstr); if (StrLen(Tempstr)==0) break; //Handle 'Status' header that changes the 1st Response line if (strncasecmp(Tempstr,"Status:",7)==0) { ptr=Tempstr+7; while (isspace(*ptr) && (*ptr != '\0')) ptr++; ResponseLine=MCopyStr(ResponseLine, Session->Protocol, " ", ptr, NULL); } else if (strncasecmp(Tempstr,"Content-Length:",15)==0) { ptr=Tempstr+15; while (isspace(*ptr)) ptr++; ContentLength=(off_t) strtoull(ptr,NULL,10); Headers=MCatStr(Headers,Tempstr,"\r\n",NULL); } else if (strncasecmp(Tempstr,"Connection:",11)==0) { ptr=Tempstr+11; while (isspace(*ptr)) ptr++; if (strncasecmp(ptr,"Keep-Alive",10)==0) KeepAlive=TRUE; Headers=MCatStr(Headers,Tempstr,"\r\n",NULL); } else Headers=MCatStr(Headers,Tempstr,"\r\n",NULL); Tempstr=STREAMReadLine(Tempstr,ParentProcessPipe); } //The second "\r\n" here will provide the blank line that marks the end //of the headers Tempstr=MCopyStr(Tempstr, ResponseLine,"\r\n",Headers,"\r\n",NULL); STREAMWriteLine(Tempstr,S); if (Settings.Flags & FLAG_LOG_MORE_VERBOSE) LogToFile(Settings.LogPath,"CGI HEADERS: [%s]",Tempstr); //Read remaining data from CGI STREAMSendFile(ParentProcessPipe, S, ContentLength,SENDFILE_KERNEL|SENDFILE_LOOP); STREAMFlush(S); //if we're running a cgi program, then it will close the session when done, so //turn off the 'reuse session' flag if (KeepAlive) Session->Flags |= SESSION_KEEPALIVE | SESSION_REUSE; else Session->Flags &= ~(SESSION_KEEPALIVE | SESSION_REUSE); DestroyString(Tempstr); DestroyString(Headers); DestroyString(ResponseLine); return(RetVal); }