00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <windows.h>
00048 #include <time.h>
00049 #include <httpext.h>
00050 #include <process.h>
00051
00052 #include "../../scriba.h"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static void IsapiStdOutFunction(char Character,
00071 LPEXTENSION_CONTROL_BLOCK lpECB
00072 ){
00073
00074
00075 static DWORD dwBytes = 1;
00076 lpECB->WriteClient(lpECB->ConnID,&Character,&dwBytes,HSE_IO_SYNC);
00077 }
00078
00079
00080
00081
00082
00083
00084 static pSbProgram pProgramConfig;
00085 static char *szCache;
00086 static char *szReportFile;
00087 static FILE *ReportFile;
00088 static CRITICAL_SECTION csReport;
00089 static char *szErrorMessage;
00090
00091 static int DoMemoryCache;
00092 static CRITICAL_SECTION csSymbolTable;
00093 static SymbolTable ProgramCache;
00094 static void *pCacheMemorySegment;
00095 typedef struct _CacheItem {
00096 pSbProgram pProgram;
00097 int boolValid;
00098 CRITICAL_SECTION csCompile;
00099 }CacheItem,*pCacheItem;
00100
00101 static void IsapiErrorScreen(LPEXTENSION_CONTROL_BLOCK lpECB){
00102 DWORD dwBytes;
00103 static char *szDefaultErrorMessage =
00104 "</PRE></FONT>\n</BODY>\n</HTML>\n";
00105
00106 if( szErrorMessage == NULL )szErrorMessage = szDefaultErrorMessage;
00107
00108 dwBytes = strlen(szErrorMessage);
00109 lpECB->WriteClient(lpECB->ConnID,szErrorMessage,&dwBytes,HSE_IO_SYNC);
00110
00111 }
00112
00113 int GetC(void *f){ return getc((FILE *)f); }
00114
00115 void isapi_report(void *vlpECB,
00116 char *FileName,
00117 long LineNumber,
00118 unsigned int iErrorCode,
00119 int iErrorSeverity,
00120 int *piErrorCounter,
00121 char *szErrorString,
00122 unsigned long *fFlags
00123 ){
00124 char timebuf[9],datebuf[9];
00125 LPEXTENSION_CONTROL_BLOCK lpECB=vlpECB;
00126 char ErrMes[256];
00127 DWORD dwBytes;
00128 static char *szErrorHeader =
00129 "HTTP/1.0 200 OK\nContent-Type: text/html\n\n"
00130 "<HTML>\n<HEAD>\n<TITLE>ScriptBasic Program Error</TITLE>\n</HEAD>\n<BODY BGCOLOR=\"WHITE\">\n"
00131 "<FONT FACE=\"VERDANA\" SIZE=\"2\">\n"
00132 "<H1>ScriptBasic Program Error</H1>\n"
00133 "An error happened while executing the program.<P>\n<FONT SIZE=\"3\"><TT>";
00134
00135 #define EMIT dwBytes = strlen(ErrMes);lpECB->WriteClient(lpECB->ConnID,ErrMes,&dwBytes,HSE_IO_SYNC)
00136
00137 if( !((*fFlags) & REPORT_F_FRST) ){
00138 dwBytes = strlen(szErrorHeader);
00139 lpECB->WriteClient(lpECB->ConnID,szErrorHeader,&dwBytes,HSE_IO_SYNC);
00140 }
00141
00142 if( szReportFile == NULL )return;
00143 EnterCriticalSection(&csReport);
00144 ReportFile = fopen(szReportFile,"a");
00145 if( ReportFile == NULL )
00146 LeaveCriticalSection(&csReport);
00147
00148 _strtime( timebuf );
00149 _strdate( datebuf );
00150 if( szErrorString && strlen(szErrorString) > 80 )szErrorString[79] = (char)0;
00151
00152 if( iErrorSeverity >= REPORT_ERROR && piErrorCounter )(*piErrorCounter)++;
00153
00154 if( ReportFile )fprintf(ReportFile,"%s %s:",datebuf,timebuf);
00155 sprintf(ErrMes,"%s %s:",datebuf,timebuf);
00156 EMIT;
00157 if( FileName && ReportFile )fprintf(ReportFile,"%s(%ld):",FileName,LineNumber);
00158 if( FileName ){
00159 sprintf(ErrMes,"%s(%ld):",FileName,LineNumber);
00160 EMIT;
00161 }
00162 if( ReportFile )
00163 fprintf(ReportFile,(iErrorCode < MAX_ERROR_CODE ? " error &H%x:" : " error 0x%08x:"),iErrorCode);
00164 sprintf(ErrMes,(iErrorCode < MAX_ERROR_CODE ? " error &H%x:" : " error 0x%08x:"),iErrorCode);
00165 EMIT;
00166 if( iErrorCode >= MAX_ERROR_CODE )iErrorCode = COMMAND_ERROR_EXTENSION_SPECIFIC;
00167 if( szErrorString ){
00168 fprintf(ReportFile,en_error_messages[iErrorCode],szErrorString);
00169 fprintf(ReportFile,"\n");
00170 }else
00171 fprintf(ReportFile,"%s\n",en_error_messages[iErrorCode]);
00172
00173 if( szErrorString ){
00174 sprintf(ErrMes,en_error_messages[iErrorCode],szErrorString);
00175 EMIT;
00176 sprintf(ErrMes,"<P>\n");
00177 EMIT;
00178 }else{
00179 sprintf(ErrMes,"%s<P>\n",en_error_messages[iErrorCode]);
00180 EMIT;
00181 }
00182 *fFlags |= REPORT_F_FRST;
00183 if( ReportFile ){
00184 fclose(ReportFile);
00185 LeaveCriticalSection(&csReport);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB
00198 ){
00199
00200
00201 pSbProgram pProgram;
00202 unsigned long fErrorFlags;
00203 int iError,iErrorCounter;
00204 char *szInputFile;
00205 char *pszPreprocessedFileName=NULL;
00206 int binarycode;
00207 #define FULL_PATH_BUFFER_LENGTH 256
00208 pCacheItem *ppCache;
00209
00210 lpECB->dwHttpStatusCode = 200;
00211
00212
00213 szInputFile = lpECB->lpszPathTranslated;
00214
00215 if( DoMemoryCache ){
00216
00217 EnterCriticalSection(&csSymbolTable);
00218 ppCache = (pCacheItem *)sym_LookupSymbol(szInputFile,
00219 ProgramCache,
00220 1,
00221 alloc_Alloc,
00222 alloc_Free,
00223 pCacheMemorySegment);
00224
00225 if( *ppCache == NULL ){
00226 *ppCache = alloc_Alloc(sizeof(CacheItem),pCacheMemorySegment);
00227 if( *ppCache == NULL ){
00228 LeaveCriticalSection(&csSymbolTable);
00229 isapi_report(stderr,"",0,COMMAND_ERROR_MEMORY_LOW,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00230 return HSE_STATUS_SUCCESS;
00231 }
00232 (*ppCache)->pProgram = NULL;
00233 InitializeCriticalSection(&((*ppCache)->csCompile));
00234 EnterCriticalSection(&((*ppCache)->csCompile));
00235 LeaveCriticalSection(&csSymbolTable);
00236 (*ppCache)->boolValid = 0;
00237 pProgram = (*ppCache)->pProgram = scriba_new(malloc,free);
00238 if( pProgram == NULL ){
00239 LeaveCriticalSection(&((*ppCache)->csCompile));
00240 LeaveCriticalSection(&csSymbolTable);
00241 isapi_report(stderr,"",0,COMMAND_ERROR_MEMORY_LOW,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00242 return HSE_STATUS_SUCCESS;
00243 }
00244 scriba_SetFileName(pProgram,szInputFile);
00245 if( scriba_UseCacheFile(pProgram) == SCRIBA_ERROR_SUCCESS )binarycode = 1;
00246 if( binarycode || scriba_IsFileBinaryFormat(pProgram) ){
00247 scriba_LoadBinaryProgram(pProgram);
00248 }else{
00249 if( iError=scriba_RunExternalPreprocessor(pProgram,NULL) ){
00250 LeaveCriticalSection(&((*ppCache)->csCompile));
00251 LeaveCriticalSection(&csSymbolTable);
00252 isapi_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00253 return HSE_STATUS_SUCCESS;
00254 }
00255 if( scriba_LoadSourceProgram(pProgram) )return HSE_STATUS_SUCCESS;
00256 scriba_SaveCacheFile(pProgram);
00257 }
00258 (*ppCache)->boolValid = 1;
00259 LeaveCriticalSection(&((*ppCache)->csCompile));
00260 }else{
00261 LeaveCriticalSection(&csSymbolTable);
00262 }
00263
00264
00265
00266 EnterCriticalSection(&((*ppCache)->csCompile));
00267 LeaveCriticalSection(&((*ppCache)->csCompile));
00268
00269
00270 if( ! (*ppCache)->boolValid ){
00271 isapi_report(stderr,"",0,COMMAND_ERROR_INVALID_CODE,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00272 return HSE_STATUS_SUCCESS;
00273 }
00274
00275 pProgram = scriba_new(malloc,free);
00276 if( pProgram == NULL ){
00277 isapi_report(stderr,"",0,COMMAND_ERROR_MEMORY_LOW,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00278 return HSE_STATUS_SUCCESS;
00279 }
00280 scriba_InheritConfiguration(pProgram,pProgramConfig);
00281 scriba_InheritBinaryProgram(pProgram,(*ppCache)->pProgram);
00282
00283
00284 }else{
00285
00286 pProgram = scriba_new(malloc,free);
00287 if( pProgram == NULL ){
00288 isapi_report(stderr,"",0,COMMAND_ERROR_MEMORY_LOW,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00289 return HSE_STATUS_SUCCESS;
00290 }
00291 scriba_InheritConfiguration(pProgram,pProgramConfig);
00292 scriba_SetFileName(pProgram,szInputFile);
00293 if( scriba_UseCacheFile(pProgram) == SCRIBA_ERROR_SUCCESS )binarycode = 1;
00294 if( binarycode || scriba_IsFileBinaryFormat(pProgram) ){
00295 scriba_LoadBinaryProgram(pProgram);
00296 }else{
00297 if( iError=scriba_RunExternalPreprocessor(pProgram,NULL) ){
00298 isapi_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00299 return HSE_STATUS_SUCCESS;
00300 }
00301 if( scriba_LoadSourceProgram(pProgram) )return HSE_STATUS_SUCCESS;
00302 scriba_SaveCacheFile(pProgram);
00303 }
00304 }
00305
00306 scriba_Run(pProgram,NULL);
00307 scriba_destroy(pProgram);
00308
00309 sprintf(lpECB->lpszLogData,"executed %s.",szInputFile);
00310 return HSE_STATUS_SUCCESS;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 BOOL WINAPI TerminateExtension(DWORD dwFlags
00321 ){
00322
00323
00324 char timebuf[9],datebuf[9];
00325
00326 switch( dwFlags ){
00327 case HSE_TERM_ADVISORY_UNLOAD:
00328 if( szReportFile != NULL ){
00329 EnterCriticalSection(&csReport);
00330 ReportFile = fopen(szReportFile,"a");
00331 if( ReportFile != NULL ){
00332 _strtime( timebuf );
00333 _strdate( datebuf );
00334 fprintf(ReportFile,"%s %s: ScriptBasic ISAPI variation was unloaded upon request.\n",datebuf,timebuf);
00335 fclose(ReportFile);
00336 }
00337 LeaveCriticalSection(&csReport);
00338 }
00339 scriba_destroy(pProgramConfig);
00340 pProgramConfig = NULL;
00341 return TRUE;
00342 case HSE_TERM_MUST_UNLOAD:
00343 if( szReportFile != NULL ){
00344 EnterCriticalSection(&csReport);
00345 ReportFile = fopen(szReportFile,"a");
00346 if( ReportFile != NULL ){
00347 _strtime( timebuf );
00348 _strdate( datebuf );
00349 fprintf(ReportFile,"%s %s: ScriptBasic ISAPI variation was forcefully unloaded.\n",datebuf,timebuf);
00350 fclose(ReportFile);
00351 }
00352 LeaveCriticalSection(&csReport);
00353 }
00354 scriba_destroy(pProgramConfig);
00355 pProgramConfig = NULL;
00356 return TRUE;
00357 default:;
00358 }
00359 return 0;
00360 }
00361
00362
00363
00364
00365
00366
00367 BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer
00368 ){
00369
00370
00371 char *szErrorMessageFile,*s;
00372 char timebuf[9],datebuf[9];
00373
00374
00375 pProgramConfig = scriba_new(malloc,free);
00376
00377
00378
00379 scriba_LoadConfiguration(pProgramConfig,NULL);
00380
00381
00382 szCache = cft_GetString(pProgramConfig->pCONF,"cache");
00383 szReportFile = cft_GetString(pProgramConfig->pCONF,"isapi.report");
00384
00385
00386 InitializeCriticalSection(&csReport);
00387
00388
00389 InitializeCriticalSection(&csSymbolTable);
00390
00391
00392 szErrorMessageFile = cft_GetString(pProgramConfig->pCONF,"isapi.errormessage");
00393
00394
00395 if( szReportFile != NULL ){
00396 EnterCriticalSection(&csReport);
00397 ReportFile = fopen(szReportFile,"a");
00398 if( ReportFile != NULL ){
00399 _strtime( timebuf );
00400 _strdate( datebuf );
00401 fprintf(ReportFile,"%s %s: ScriptBasic ISAPI variation was loaded.\n",datebuf,timebuf);
00402 fclose(ReportFile);
00403 }
00404 LeaveCriticalSection(&csReport);
00405 }
00406
00407
00408
00409
00410
00411 s = cft_GetString(pProgramConfig->pCONF,"isapi.memcache");
00412 if( s && !strcmp(s,"yes") ){
00413 pCacheMemorySegment = alloc_InitSegment(malloc,free);
00414 if( pCacheMemorySegment == NULL )return FALSE;
00415 ProgramCache = sym_NewSymbolTable(alloc_Alloc,pCacheMemorySegment);
00416 if( ProgramCache == NULL )return FALSE;
00417 DoMemoryCache = 1;
00418 }else{
00419 DoMemoryCache = 0;
00420 pCacheMemorySegment = NULL;
00421 ProgramCache = NULL;
00422 }
00423
00424 pVer->dwExtensionVersion = HSE_VERSION;
00425 return TRUE;
00426 }