X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=libfcgi%2Ffcgiapp.c;h=23e55ac087b3804e6025bc21d0886fad0ca8192d;hb=55d1f206f2bd7400f6f5f6677f7a2edadfa113e0;hp=240247ccc10b4fcbaee736474685e6fe2b5bb708;hpb=0b7c966217f1925995ff9fd045dea735f99d3483;p=catagits%2Ffcgi2.git diff --git a/libfcgi/fcgiapp.c b/libfcgi/fcgiapp.c index 240247c..23e55ac 100644 --- a/libfcgi/fcgiapp.c +++ b/libfcgi/fcgiapp.c @@ -11,15 +11,9 @@ * */ #ifndef lint -static const char rcsid[] = "$Id: fcgiapp.c,v 1.8 1999/08/05 21:25:53 roberts Exp $"; +static const char rcsid[] = "$Id: fcgiapp.c,v 1.24 2001/06/22 09:12:03 skimo Exp $"; #endif /* not lint */ -#include "fcgi_config.h" - -#ifdef _WIN32 -#define DLLAPI __declspec(dllexport) -#endif - #include #include #include /* for fcntl */ @@ -31,6 +25,8 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.8 1999/08/05 21:25:53 roberts Ex #include #include +#include "fcgi_config.h" + #ifdef HAVE_SYS_SOCKET_H #include /* for getpeername */ #endif @@ -43,11 +39,20 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.8 1999/08/05 21:25:53 roberts Ex #include #endif -#include "fcgimisc.h" +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef _WIN32 +#define DLLAPI __declspec(dllexport) +#endif + +#include "fcgiapp.h" #include "fcgiappmisc.h" + +#include "fcgimisc.h" #include "fastcgi.h" #include "fcgios.h" -#include "fcgiapp.h" /* * This is a workaround for one version of the HP C compiler @@ -64,9 +69,9 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.8 1999/08/05 21:25:53 roberts Ex * Globals */ static int libInitialized = 0; +static int isFastCGI = -1; static char *webServerAddressList = NULL; -static FCGX_Request reqData; -static FCGX_Request *reqDataPtr = &reqData; +static FCGX_Request the_request; static void *Malloc(size_t size) { @@ -184,6 +189,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) { int c; char *p = str; + n--; while (n > 0) { c = FCGX_GetChar(stream); @@ -193,7 +199,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) else break; } - *p++ = c; + *p++ = (char) c; n--; if(c == '\n') break; @@ -223,7 +229,7 @@ int FCGX_UnGetChar(int c, FCGX_Stream *stream) { || stream->rdNext == stream->stopUnget) return EOF; --(stream->rdNext); - *stream->rdNext = c; + *stream->rdNext = (unsigned char) c; return c; } @@ -264,12 +270,12 @@ int FCGX_HasSeenEOF(FCGX_Stream *stream) { int FCGX_PutChar(int c, FCGX_Stream *stream) { if(stream->wrNext != stream->stop) - return (*stream->wrNext++ = c); + return (*stream->wrNext++ = (unsigned char) c); if(stream->isClosed || stream->isReader) return EOF; stream->emptyBuffProc(stream, FALSE); if(stream->wrNext != stream->stop) - return (*stream->wrNext++ = c); + return (*stream->wrNext++ = (unsigned char) c); ASSERT(stream->isClosed); /* bug in emptyBuffProc if not */ return EOF; } @@ -393,8 +399,8 @@ static void CopyAndAdvance(char **destPtr, char **srcPtr, int n); int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) { char *f, *fStop, *percentPtr, *p, *fmtBuffPtr, *buffPtr; - int op, performedOp, sizeModifier, buffCount, buffLen, specifierLength; - int fastPath, n, auxBuffLen, buffReqd, minWidth, precision, exp; + int op, performedOp, sizeModifier, buffCount = 0, buffLen, specifierLength; + int fastPath, n, auxBuffLen = 0, buffReqd, minWidth, precision, exp; char *auxBuffPtr = NULL; int streamCount = 0; char fmtBuff[FMT_BUFFLEN]; @@ -406,13 +412,13 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) unsigned unsignedArg; unsigned long uLongArg; unsigned short uShortArg; - char *charPtrArg; + char *charPtrArg = NULL; void *voidPtrArg; int *intPtrArg; long *longPtrArg; short *shortPtrArg; - double doubleArg; - LONG_DOUBLE lDoubleArg; + double doubleArg = 0.0; + LONG_DOUBLE lDoubleArg = 0.0L; fmtBuff[0] = '%'; f = (char *) format; @@ -421,7 +427,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) percentPtr = (char *)memchr(f, '%', fStop - f); if(percentPtr == NULL) percentPtr = fStop; if(percentPtr != f) { - if(FCGX_PutStr(f, percentPtr - f, stream) < 0) goto ErrorReturn; + if(FCGX_PutStr(f, percentPtr - f, stream) < 0) + goto ErrorReturn; streamCount += percentPtr - f; f = percentPtr; if(f == fStop) break; @@ -450,14 +457,14 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) case 'h': sizeModifier = op; op = *(percentPtr + 2); - fmtBuff[1] = sizeModifier; - fmtBuff[2] = op; + fmtBuff[1] = (char) sizeModifier; + fmtBuff[2] = (char) op; fmtBuff[3] = '\0'; specifierLength = 3; break; default: sizeModifier = ' '; - fmtBuff[1] = op; + fmtBuff[1] = (char) op; fmtBuff[2] = '\0'; specifierLength = 2; break; @@ -477,7 +484,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) * Scan flags */ n = strspn(p, "-0+ #"); - if(n > 5) goto ErrorReturn; + if(n > 5) + goto ErrorReturn; CopyAndAdvance(&fmtBuffPtr, &p, n); /* * Scan minimum field width @@ -486,7 +494,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) if(n == 0) { if(*p == '*') { minWidth = va_arg(arg, int); - if(abs(minWidth) > 999999) goto ErrorReturn; + if(abs(minWidth) > 999999) + goto ErrorReturn; /* * The following use of strlen rather than the * value returned from sprintf is because SUNOS4 @@ -514,7 +523,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) if(*p == '*') { precision = va_arg(arg, int); if(precision < 0) precision = 0; - if(precision > 999999) goto ErrorReturn; + if(precision > 999999) + goto ErrorReturn; /* * The following use of strlen rather than the * value returned from sprintf is because SUNOS4 @@ -571,6 +581,7 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) break; case 's': charPtrArg = va_arg(arg, char *); + if (!charPtrArg) charPtrArg = "(null)"; if(precision == -1) { buffReqd = strlen(charPtrArg); } else { @@ -583,11 +594,13 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) switch(sizeModifier) { case ' ': doubleArg = va_arg(arg, double); - frexp(doubleArg, &exp); + frexp(doubleArg, &exp); break; case 'L': lDoubleArg = va_arg(arg, LONG_DOUBLE); - frexp(lDoubleArg, &exp); + /* XXX Need to check for the presence of + * frexpl() and use it if available */ + frexp((double) lDoubleArg, &exp); break; default: goto ErrorReturn; @@ -620,7 +633,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) if(auxBuffPtr != NULL) free(auxBuffPtr); auxBuffPtr = (char *)Malloc(buffReqd); auxBuffLen = buffReqd; - if(auxBuffPtr == NULL) goto ErrorReturn; + if(auxBuffPtr == NULL) + goto ErrorReturn; } buffPtr = auxBuffPtr; buffLen = auxBuffLen; @@ -655,8 +669,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) buffCount = strlen(buffPtr); break; case 'h': - shortArg = va_arg(arg, short); - sprintf(buffPtr, fmtBuff, shortArg); + shortArg = (short) va_arg(arg, int); + sprintf(buffPtr, fmtBuff, shortArg); buffCount = strlen(buffPtr); break; default: @@ -679,8 +693,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) buffCount = strlen(buffPtr); break; case 'h': - uShortArg = va_arg(arg, unsigned short); - sprintf(buffPtr, fmtBuff, uShortArg); + uShortArg = (unsigned short) va_arg(arg, int); + sprintf(buffPtr, fmtBuff, uShortArg); buffCount = strlen(buffPtr); break; default: @@ -728,7 +742,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) } break; case 'p': - if(sizeModifier != ' ') goto ErrorReturn; + if(sizeModifier != ' ') + goto ErrorReturn; voidPtrArg = va_arg(arg, void *); sprintf(buffPtr, fmtBuff, voidPtrArg); buffCount = strlen(buffPtr); @@ -744,8 +759,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) *longPtrArg = streamCount; break; case 'h': - shortPtrArg = va_arg(arg, short *); - *shortPtrArg = streamCount; + shortPtrArg = (short *) va_arg(arg, short *); + *shortPtrArg = (short) streamCount; break; default: goto ErrorReturn; @@ -802,7 +817,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) break; } /* switch(op) */ if(performedOp) break; - if(!fastPath) goto ErrorReturn; + if(!fastPath) + goto ErrorReturn; fastPath = FALSE; } /* for (;;) */ ASSERT(buffCount < buffLen); @@ -883,6 +899,8 @@ int FCGX_FFlush(FCGX_Stream *stream) */ int FCGX_FClose(FCGX_Stream *stream) { + if (stream == NULL) return 0; + if(!stream->wasFCloseCalled) { if(!stream->isReader) { stream->emptyBuffProc(stream, TRUE); @@ -1073,9 +1091,12 @@ char *FCGX_GetParam(const char *name, FCGX_ParamArray envp) { int len; char **p; + + if (name == NULL || envp == NULL) return NULL; + len = strlen(name); - if(len == 0) return NULL; - for (p = envp; *p != NULL; p++) { + + for (p = envp; *p; ++p) { if((strncmp(name, *p, len) == 0) && ((*p)[len] == '=')) { return *p+len+1; } @@ -1174,12 +1195,12 @@ static FCGI_Header MakeHeader( ASSERT(contentLength >= 0 && contentLength <= FCGI_MAX_LENGTH); ASSERT(paddingLength >= 0 && paddingLength <= 0xff); header.version = FCGI_VERSION_1; - header.type = type; - header.requestIdB1 = (requestId >> 8) & 0xff; - header.requestIdB0 = (requestId ) & 0xff; - header.contentLengthB1 = (contentLength >> 8) & 0xff; - header.contentLengthB0 = (contentLength ) & 0xff; - header.paddingLength = paddingLength; + header.type = (unsigned char) type; + header.requestIdB1 = (unsigned char) ((requestId >> 8) & 0xff); + header.requestIdB0 = (unsigned char) ((requestId ) & 0xff); + header.contentLengthB1 = (unsigned char) ((contentLength >> 8) & 0xff); + header.contentLengthB0 = (unsigned char) ((contentLength ) & 0xff); + header.paddingLength = (unsigned char) paddingLength; header.reserved = 0; return header; } @@ -1198,11 +1219,11 @@ static FCGI_EndRequestBody MakeEndRequestBody( int protocolStatus) { FCGI_EndRequestBody body; - body.appStatusB3 = (appStatus >> 24) & 0xff; - body.appStatusB2 = (appStatus >> 16) & 0xff; - body.appStatusB1 = (appStatus >> 8) & 0xff; - body.appStatusB0 = (appStatus ) & 0xff; - body.protocolStatus = protocolStatus; + body.appStatusB3 = (unsigned char) ((appStatus >> 24) & 0xff); + body.appStatusB2 = (unsigned char) ((appStatus >> 16) & 0xff); + body.appStatusB1 = (unsigned char) ((appStatus >> 8) & 0xff); + body.appStatusB0 = (unsigned char) ((appStatus ) & 0xff); + body.protocolStatus = (unsigned char) protocolStatus; memset(body.reserved, 0, sizeof(body.reserved)); return body; } @@ -1220,7 +1241,7 @@ static FCGI_UnknownTypeBody MakeUnknownTypeBody( int type) { FCGI_UnknownTypeBody body; - body.type = type; + body.type = (unsigned char) type; memset(body.reserved, 0, sizeof(body.reserved)); return body; } @@ -1424,7 +1445,7 @@ static int ProcessManagementRecord(int type, FCGX_Stream *stream) char **pPtr; char response[64]; /* 64 = 8 + 3*(1+1+14+1)* + padding */ char *responseP = &response[FCGI_HEADER_LEN]; - char *name, value; + char *name, value = '\0'; int len, paddedLen; if(type == FCGI_GET_VALUES) { ReadParams(paramsPtr, stream); @@ -1902,17 +1923,10 @@ FCGX_Stream *CreateWriter( * Results: * TRUE if the process is a CGI process, FALSE if FastCGI. * - * Side effects: - * If this is a FastCGI process there's a chance that a connection - * will be accepted while performing the test. If this occurs, - * the connection is saved and used later by the FCGX_Accept logic. - * *---------------------------------------------------------------------- */ int FCGX_IsCGI(void) { - static int isFastCGI = -1; - if (isFastCGI != -1) { return !isFastCGI; } @@ -1952,7 +1966,7 @@ int FCGX_IsCGI(void) void FCGX_Finish(void) { - FCGX_Finish_r(reqDataPtr); + FCGX_Finish_r(&the_request); } /* @@ -1980,34 +1994,46 @@ void FCGX_Finish_r(FCGX_Request *reqDataPtr) return; } + /* This should probably use a 'status' member instead of 'in' */ if (reqDataPtr->in) { int errStatus = FCGX_FClose(reqDataPtr->err); int outStatus = FCGX_FClose(reqDataPtr->out); - if (errStatus || outStatus - || FCGX_GetError(reqDataPtr->in) - || !reqDataPtr->keepConnection) + if (errStatus || outStatus || FCGX_GetError(reqDataPtr->in)) { OS_IpcClose(reqDataPtr->ipcFd); + reqDataPtr->ipcFd = -1; } + } - ASSERT(reqDataPtr->nWriters == 0); + FCGX_Free(reqDataPtr); +} - FreeStream(&reqDataPtr->in); - FreeStream(&reqDataPtr->out); - FreeStream(&reqDataPtr->err); +void FCGX_Free(FCGX_Request * request) +{ + if (request == NULL) + return; - FreeParams(&reqDataPtr->paramsPtr); - } + FreeStream(&request->in); + FreeStream(&request->out); + FreeStream(&request->err); + FreeParams(&request->paramsPtr); - if (!reqDataPtr->keepConnection) { - reqDataPtr->ipcFd = -1; + if (!request->keepConnection) + { + OS_IpcClose(request->ipcFd); + request->ipcFd = -1; } } int FCGX_OpenSocket(const char *path, int backlog) { - return OS_CreateLocalIpcFd(path, backlog); + int rc = OS_CreateLocalIpcFd(path, backlog); + if (rc == FCGI_LISTENSOCK_FILENO && isFastCGI == 0) { + /* XXX probably need to call OS_LibInit() again for Win */ + isFastCGI = 1; + } + return rc; } int FCGX_InitRequest(FCGX_Request *request, int sock, int flags) @@ -2020,6 +2046,8 @@ int FCGX_InitRequest(FCGX_Request *request, int sock, int flags) /* @@@ Should validate against "known" flags */ request->flags = flags; + request->ipcFd = -1; + return 0; } @@ -2047,14 +2075,14 @@ int FCGX_Init(void) /* If our compiler doesn't play by the ISO rules for struct layout, halt. */ ASSERT(sizeof(FCGI_Header) == FCGI_HEADER_LEN); - FCGX_InitRequest(&reqData, FCGI_LISTENSOCK_FILENO, 0); + FCGX_InitRequest(&the_request, FCGI_LISTENSOCK_FILENO, 0); if (OS_LibInit(NULL) == -1) { return OS_Errno ? OS_Errno : -9997; } p = getenv("FCGI_WEB_SERVER_ADDRS"); - webServerAddressList = p ? StringCopy(p) : ""; + webServerAddressList = p ? StringCopy(p) : NULL; libInitialized = 1; return 0; @@ -2094,14 +2122,23 @@ int FCGX_Accept( FCGX_Stream **err, FCGX_ParamArray *envp) { - if (!libInitialized) { - int rc = FCGX_Init(); + int rc; + + if (! libInitialized) { + rc = FCGX_Init(); if (rc) { - return (rc < 0) ? rc : -rc; + return rc; } } - return FCGX_Accept_r(&reqData); + rc = FCGX_Accept_r(&the_request); + + *in = the_request.in; + *out = the_request.out; + *err = the_request.err; + *envp = the_request.envp; + + return rc; } /* @@ -2133,11 +2170,6 @@ int FCGX_Accept( */ int FCGX_Accept_r(FCGX_Request *reqDataPtr) { - FCGX_Stream **in = &reqDataPtr->in; - FCGX_Stream **out = &reqDataPtr->out; - FCGX_Stream **err = &reqDataPtr->err; - FCGX_ParamArray *envp = &reqDataPtr->envp; - if (!libInitialized) { return -9998; } @@ -2196,14 +2228,14 @@ int FCGX_Accept_r(FCGX_Request *reqDataPtr) */ break; } + /* * Close the connection and try again. */ - TryAgain: - FreeParams(&reqDataPtr->paramsPtr); - FreeStream(&reqDataPtr->in); - OS_Close(reqDataPtr->ipcFd); - reqDataPtr->ipcFd = -1; +TryAgain: + reqDataPtr->keepConnection = 0; + FCGX_Free(reqDataPtr); + } /* for (;;) */ /* * Build the remaining data structures representing the new @@ -2213,10 +2245,7 @@ int FCGX_Accept_r(FCGX_Request *reqDataPtr) reqDataPtr->out = NewWriter(reqDataPtr, 8192, FCGI_STDOUT); reqDataPtr->err = NewWriter(reqDataPtr, 512, FCGI_STDERR); reqDataPtr->nWriters = 2; - *in = reqDataPtr->in; - *out = reqDataPtr->out; - *err = reqDataPtr->err; - *envp = reqDataPtr->paramsPtr->vec; + reqDataPtr->envp = reqDataPtr->paramsPtr->vec; return 0; } @@ -2248,7 +2277,7 @@ int FCGX_StartFilterData(FCGX_Stream *stream) SetError(stream, FCGX_CALL_SEQ_ERROR); return -1; } - SetReaderType(reqDataPtr->in, FCGI_DATA); + SetReaderType(stream, FCGI_DATA); return 0; }