0001 |
/* |
0002 |
* Copyright 2001 Alexander Boverman and the original authors. |
0003 |
* |
0004 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
0005 |
* you may not use this file except in compliance with the License. |
0006 |
* You may obtain a copy of the License at |
0007 |
* |
0008 |
* http://www.apache.org/licenses/LICENSE-2.0 |
0009 |
* |
0010 |
* Unless required by applicable law or agreed to in writing, software |
0011 |
* distributed under the License is distributed on an "AS IS" BASIS, |
0012 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
0013 |
* See the License for the specific language governing permissions and |
0014 |
* limitations under the License. |
0015 |
*/ |
0016 |
|
0017 |
#include "WtInitCmds.h" |
0018 |
#include "WtSettings.h" |
0019 |
#include "WtUtil.h" |
0020 |
#include "WtWebErrors.h" |
0021 |
#include "WtTable.h" |
0022 |
#include "WtTableUtil.h" |
0023 |
#include "WtTableCmds.h" |
0024 |
#include "WtExecute.h" |
0025 |
#include "WtServerCmds.h" |
0026 |
#include "WtBasicCmds.h" |
0027 |
#include "WtClientRequest.h" |
0028 |
#include "WtResponse.h" |
0029 |
#include "WtUpload.h" |
0030 |
#include "WtCookie.h" |
0031 |
#include "WtDbSession.h" |
0032 |
#include "WtContextEvents.h" |
0033 |
#include "WtProcSession.h" |
0034 |
#include "WtAppTable.h" |
0035 |
|
0036 |
int WtInitInterpCmdInternal(Tcl_Obj *const objv[], int objc, Tcl_Interp *interp) |
0037 |
{ |
0038 |
int ok = 1, i, initRequest = 0; |
0039 |
WtContext *w = WtGetAssocContext(interp); |
0040 |
Tcl_Obj *args[4]; |
0041 |
|
0042 |
const char *namespaceList[] = { |
0043 |
"::wt::", |
0044 |
"::wt::internal::", |
0045 |
"::wt::server::", |
0046 |
"::wt::page::", |
0047 |
"::wt::request::", |
0048 |
"::wt::response::", |
0049 |
"::wt::web::", |
0050 |
"::wt::session::", |
0051 |
"::wt::util::" |
0052 |
}; |
0053 |
|
0054 |
if (Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])) != 0) { |
0055 |
WtInterpError(HERE, w, interp); |
0056 |
ok = 0; |
0057 |
} |
0058 |
|
0059 |
if (ok) { |
0060 |
if (Tcl_GetBooleanFromObj(interp, objv[1], &initRequest) != TCL_OK) { |
0061 |
WtInterpError(HERE, w, interp); |
0062 |
ok = 0; |
0063 |
} else if (initRequest) { |
0064 |
w->web->interpRequestCount++; |
0065 |
w->web->deleteInterp = !w->web->isPersistent; |
0066 |
if (!WtInitCtxEventHandlers(w, interp)) { |
0067 |
WtInterpError(HERE, w, interp); |
0068 |
ok = 0; |
0069 |
} |
0070 |
} |
0071 |
} |
0072 |
|
0073 |
if (ok && w->web->interpIsNew) { |
0074 |
/* Eval the interp init script */ |
0075 |
|
0076 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "initInterp", |
0077 |
interp, w)) { |
0078 |
WtInterpError(HERE, w, interp); |
0079 |
ok = 0; |
0080 |
} |
0081 |
|
0082 |
/* Create the command namespaces */ |
0083 |
|
0084 |
if (ok) { |
0085 |
for (i = 0; i < sizeof(namespaceList) / sizeof(const char *); ++i) { |
0086 |
args[0] = WtNewString("namespace"); |
0087 |
args[1] = WtNewString("eval"); |
0088 |
args[2] = WtNewString(namespaceList[i]); |
0089 |
args[3] = WtNewString(NULL); |
0090 |
|
0091 |
if (WtEvalIncr(interp, 4, args, TCL_EVAL_DIRECT) != TCL_OK) { |
0092 |
WtInterpError(HERE, w, interp); |
0093 |
ok = 0; |
0094 |
break; |
0095 |
} |
0096 |
} |
0097 |
} |
0098 |
|
0099 |
if (ok && !WtInitTaskObjectsB(w)) { |
0100 |
WtInterpError(HERE, w, interp); |
0101 |
ok = 0; |
0102 |
} |
0103 |
|
0104 |
if (ok) { |
0105 |
/* Bind the commands */ |
0106 |
|
0107 |
WtInitTableCommands(interp); |
0108 |
WtInitPageCommands(interp); |
0109 |
WtInitServerCommands(interp); |
0110 |
WtInitBasicCommands(interp); |
0111 |
WtInitAppTableCommands(interp); |
0112 |
WtInitClientRequestCommands(interp); |
0113 |
WtInitResponseCommands(interp); |
0114 |
WtInitUploadCommands(interp); |
0115 |
WtInitCookieCommands(interp); |
0116 |
WtInitSessionCommands(interp); |
0117 |
WtInitDbSessionCommands(interp); |
0118 |
WtInitProcSessionCommands(interp); |
0119 |
|
0120 |
/* The wt::core package will be present if the module |
0121 |
is initialized */ |
0122 |
|
0123 |
if (Tcl_PkgProvide(interp, "wt::core", "1") != TCL_OK) { |
0124 |
WtInterpError(HERE, w, interp); |
0125 |
ok = 0; |
0126 |
} |
0127 |
} |
0128 |
} |
0129 |
|
0130 |
Tcl_SetObjResult(interp, WtNewBool(ok)); |
0131 |
|
0132 |
return TCL_OK; |
0133 |
} |
0134 |
|
0135 |
int WtInitPackagesCmdInternal(Tcl_Obj *const objv[], int objc, Tcl_Interp *interp) |
0136 |
{ |
0137 |
int ok = 1, i, initPackages = 0; |
0138 |
WtContext *w = WtGetAssocContext(interp); |
0139 |
Tcl_Obj *importCmd[3], *boolObj, *regCmd[3]; |
0140 |
|
0141 |
const char *packageList[] = { |
0142 |
"wt", |
0143 |
"wt::server", |
0144 |
"wt::page", |
0145 |
"wt::request", |
0146 |
"wt::response", |
0147 |
"wt::web", |
0148 |
"wt::session", |
0149 |
"wt::util", |
0150 |
"wt::contextInfo", |
0151 |
"wt::database::dbManager", |
0152 |
"wt::session::dbSession::odbcSession::sqlServerSession", |
0153 |
"wt::server::setup" |
0154 |
}; |
0155 |
|
0156 |
const char *patternList[] = { |
0157 |
"::wt::*", |
0158 |
"::wt::server::*", |
0159 |
"::wt::page::*", |
0160 |
"::wt::request::*", |
0161 |
"::wt::response::*", |
0162 |
"::wt::web::*", |
0163 |
"::wt::session::*", |
0164 |
"::wt::util::*", |
0165 |
"::wt::contextInfo::*", |
0166 |
"::wt::database::dbManager::*", |
0167 |
"::wt::server::setup::*" |
0168 |
}; |
0169 |
|
0170 |
if (Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])) != 0) { |
0171 |
ok = 0; |
0172 |
} |
0173 |
|
0174 |
/* Load the packages */ |
0175 |
|
0176 |
if (ok) { |
0177 |
if (!w->web->packageLoadDone) { |
0178 |
initPackages = 1; |
0179 |
} |
0180 |
for (i = 0; i < sizeof(packageList) / sizeof(char *); ++i) { |
0181 |
if (Tcl_PkgRequire(interp, packageList[i], NULL, 0) == NULL) { |
0182 |
ok = 0; |
0183 |
break; |
0184 |
} |
0185 |
} |
0186 |
|
0187 |
if (ok) { |
0188 |
w->web->packageLoadDone = 1; |
0189 |
} |
0190 |
} |
0191 |
|
0192 |
/* Import the core commands */ |
0193 |
|
0194 |
if (ok && w->web->importCommands) { |
0195 |
if (!WtOwnTable(&w->web->usedNamespaces, interp)) { |
0196 |
ok = 0; |
0197 |
} else if (!WtTableHas(w->web->usedNamespaces, w->web->taskNamespace)) { |
0198 |
for (i = 0; i < sizeof(patternList) / sizeof(char *); ++i) { |
0199 |
importCmd[0] = WtNewString("namespace"); |
0200 |
importCmd[1] = WtNewString("import"); |
0201 |
importCmd[2] = WtNewString(patternList[i]); |
0202 |
|
0203 |
if (WtEvalIncr(interp, 3, importCmd, 0) != TCL_OK) { |
0204 |
ok = 0; |
0205 |
break; |
0206 |
} |
0207 |
} |
0208 |
|
0209 |
if (ok) { |
0210 |
boolObj = WtNewBool(1); |
0211 |
Tcl_IncrRefCount(boolObj); |
0212 |
WtTableSet(w->web->usedNamespaces, w->web->taskNamespace, |
0213 |
boolObj); |
0214 |
Tcl_DecrRefCount(boolObj); |
0215 |
} |
0216 |
} |
0217 |
} |
0218 |
|
0219 |
/* Init settings */ |
0220 |
|
0221 |
if (ok) { |
0222 |
if (!WtConvertToTable(w->web->taskSettings, interp)) { |
0223 |
ok = 0; |
0224 |
} else if (!WtInitWebSettings(w, w->web->taskSettings, interp)) { |
0225 |
ok = 0; |
0226 |
} |
0227 |
} |
0228 |
|
0229 |
/* Load packages script */ |
0230 |
|
0231 |
if (ok && initPackages) { |
0232 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "loadPackages", |
0233 |
interp, w)) { |
0234 |
ok = 0; |
0235 |
} |
0236 |
} |
0237 |
|
0238 |
/* Init DB settings */ |
0239 |
|
0240 |
if (ok && Tcl_GetCharLength(w->web->dataSourceHandler)) { |
0241 |
regCmd[0] = WtNewString("::wt::database::dbManager::registerDataSource"); |
0242 |
regCmd[1] = WtNewString("wtDb"); |
0243 |
regCmd[2] = w->web->dataSourceHandler; |
0244 |
if (WtEvalIncr(interp, 3, regCmd, 0) != TCL_OK) { |
0245 |
ok = 0; |
0246 |
} |
0247 |
} |
0248 |
|
0249 |
if (!ok) { |
0250 |
WtInterpError(HERE, w, interp); |
0251 |
} |
0252 |
|
0253 |
Tcl_SetObjResult(interp, WtNewBool(ok)); |
0254 |
|
0255 |
return TCL_OK; |
0256 |
} |
0257 |
|
0258 |
int WtStartRequestCmdInternal(Tcl_Obj *const objv[], int objc, Tcl_Interp *interp) |
0259 |
{ |
0260 |
int ok = 1; |
0261 |
WtContext *w = WtGetAssocContext(interp); |
0262 |
|
0263 |
if (Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])) != 0) { |
0264 |
ok = 0; |
0265 |
} |
0266 |
|
0267 |
/* Start worker script */ |
0268 |
|
0269 |
if (ok && w->requestCount == 1) { |
0270 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "startWorker", |
0271 |
interp, w)) { |
0272 |
ok = 0; |
0273 |
} |
0274 |
} |
0275 |
|
0276 |
/* Create interp script */ |
0277 |
|
0278 |
if (ok && w->web->interpIsNew) { |
0279 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "createInterp", |
0280 |
interp, w)) { |
0281 |
ok = 0; |
0282 |
} |
0283 |
} |
0284 |
|
0285 |
/* Start request script */ |
0286 |
|
0287 |
if (ok) { |
0288 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "startRequest", |
0289 |
interp, w)) { |
0290 |
ok = 0; |
0291 |
} |
0292 |
} |
0293 |
|
0294 |
if (!ok) { |
0295 |
WtInterpError(HERE, w, interp); |
0296 |
} |
0297 |
|
0298 |
Tcl_SetObjResult(interp, WtNewBool(ok)); |
0299 |
|
0300 |
return ok; |
0301 |
} |
0302 |
|
0303 |
int WtEndRequestCmdInternal(Tcl_Obj *const objv[], int objc, Tcl_Interp *interp) |
0304 |
{ |
0305 |
int ok = 1; |
0306 |
WtContext *w = WtGetAssocContext(interp); |
0307 |
|
0308 |
if (Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])) != 0) { |
0309 |
WtInterpError(HERE, w, w->web->interp); |
0310 |
ok = 0; |
0311 |
} |
0312 |
|
0313 |
/* End request script */ |
0314 |
|
0315 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "endRequest", |
0316 |
interp, w)) { |
0317 |
WtInterpError(HERE, w, w->web->interp); |
0318 |
ok = 0; |
0319 |
} |
0320 |
|
0321 |
/* Finalize the session */ |
0322 |
|
0323 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "endSession", |
0324 |
interp, w)) { |
0325 |
WtInterpError(HERE, w, w->web->interp); |
0326 |
ok = 0; |
0327 |
} |
0328 |
|
0329 |
if (w->web->session.isInitialized) { |
0330 |
if (!WtSessionEndRequest(&w->web->session, interp)) { |
0331 |
WtInterpError(HERE, w, w->web->interp); |
0332 |
ok = 0; |
0333 |
} |
0334 |
} |
0335 |
|
0336 |
/* Interp delete script */ |
0337 |
|
0338 |
if (!w->web->isPersistent || w->web->deleteInterp) { |
0339 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "deleteInterp", |
0340 |
interp, w)) { |
0341 |
ok = 0; |
0342 |
} |
0343 |
} |
0344 |
|
0345 |
/* Rest interp script * |
0346 |
|
0347 |
if (ok && w->web->isPersistent && !w->web->deleteInterp) { |
0348 |
if (!WtEvalEventHandlers(&w->web->ctxEventHandlers, "restInterp", |
0349 |
interp, w)) { |
0350 |
ok = 0; |
0351 |
} |
0352 |
} |
0353 |
|
0354 |
/* Need to consume the client input (?) */ |
0355 |
|
0356 |
if (!WtParseRequest(w, w->web->interp)) { |
0357 |
WtInterpError(HERE, w, w->web->interp); |
0358 |
w->web->terminate = 1; |
0359 |
ok = 0; |
0360 |
} |
0361 |
|
0362 |
Tcl_SetObjResult(interp, WtNewBool(ok)); |
0363 |
|
0364 |
return TCL_OK; |
0365 |
} |
0366 |
|
0367 |
int WtInitInterpCmd(ClientData clientData, Tcl_Interp *interp, |
0368 |
int objc, Tcl_Obj *const objv[]) |
0369 |
{ |
0370 |
WtInitInterpCmdInternal(objv, objc, interp); |
0371 |
return TCL_OK; |
0372 |
} |
0373 |
|
0374 |
int WtInitPackagesCmd(ClientData clientData, Tcl_Interp *interp, |
0375 |
int objc, Tcl_Obj *const objv[]) |
0376 |
{ |
0377 |
WtInitPackagesCmdInternal(objv, objc, interp); |
0378 |
return TCL_OK; |
0379 |
} |
0380 |
|
0381 |
int WtStartRequestCmd(ClientData clientData, Tcl_Interp *interp, |
0382 |
int objc, Tcl_Obj *const objv[]) |
0383 |
{ |
0384 |
WtStartRequestCmdInternal(objv, objc, interp); |
0385 |
return TCL_OK; |
0386 |
} |
0387 |
|
0388 |
int WtEndRequestCmd(ClientData clientData, Tcl_Interp *interp, |
0389 |
int objc, Tcl_Obj *const objv[]) |
0390 |
{ |
0391 |
WtEndRequestCmdInternal(objv, objc, interp); |
0392 |
return TCL_OK; |
0393 |
} |