View Source

[modwtcl]
apreq.h
dist/
libapreq1/
mod_wtcl.c
mod_wtcl.h
setupExclude.txt
util/
win.def
win.mak
wt1.1/
WtAppTable.c
WtAppTable.h
WtBasicCmds.c
WtBasicCmds.h
WtClientRequest.c
WtClientRequest.h
WtCollection.c
WtCollection.h
WtCollectionCmds.c
WtCollectionCmds.h
WtContext.c
WtContext.h
WtContextEvents.c
WtContextEvents.h
WtCookie.c
WtCookie.h
WtDbSession.c
WtDbSession.h
WtExecute.c
WtExecute.h
WtHtmlEntities.c
WtHtmlEntities.h
WtInitCmds.c
WtInitCmds.h
WtMtTable.c
WtMtTable.h
WtMultiTable.c
WtMultiTable.h
WtOS.h
WtProcSession.c
WtProcSession.h
WtResponse.c
WtResponse.h
WtServerCmds.c
WtServerCmds.h
WtSession.c
WtSession.h
WtSettings.c
WtSettings.h
WtTable.c
WtTable.h
WtTableCmds.c
WtTableCmds.h
WtTableUtil.c
WtTableUtil.h
WtUpload.c
WtUpload.h
WtUtil.c
WtUtil.h
WtWebErrors.c
WtWebErrors.h
WtWindows.h
File: / archive / modwtcl / WtContextEvents.c

Lines Size Modified Created Owner MIME Types
476 12,276 2010/05/09 04:03:26 2011/06/13 15:35:15 BUILTIN\Administrators text/x-csrc

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 "WtOS.h"
0018
#include "WtContextEvents.h"
0019
#include "WtTableCmds.h"
0020
#include "WtTable.h"
0021
#include "WtTableUtil.h"
0022
#include "WtUtil.h"
0023
#include "WtBasicCmds.h"
0024
#include "WtWebErrors.h"
0025
0026
/* Eval event handler scripts */
0027
0028
int WtEvalEventHandlers(Tcl_Obj **tablePtr, const char *name,
0029
    Tcl_Interp *interp, WtContext *w)
0030
{
0031
  int ok = 1, i, len, isNewHandler, isNewList, isNewTable, status,
0032
    eventStatus = WT_STATUS_OK, errorSetId = -1;
0033
  Tcl_Obj *list, *handler, *script, *str;
0034
  char errMsg[512];
0035
0036
  if (!WtStartErrors(w, interp, &errorSetId)) {
0037
    return 0;
0038
  }
0039
0040
  list = WtTableGetObjFromStr(*tablePtr, name, NULL);
0041
0042
  if (list) {
0043
    if (Tcl_ListObjLength(interp, list, &len) != TCL_OK) {
0044
      ok = 0;
0045
    } else if (len) {
0046
      for (i = 0; i < len; i++) {
0047
        if (Tcl_ListObjIndex(interp, list, i, &handler) != TCL_OK) {
0048
          ok = 0;
0049
          WtAddInterpError(interp, w);
0050
          break;
0051
        }
0052
0053
        if (!WtConvertToTable(handler, interp)) {
0054
          ok = 0;
0055
          WtAddInterpError(interp, w);
0056
          break;
0057
        }
0058
0059
        script = WtTableGetObjFromStr(handler, "script", NULL);
0060
0061
        if (!script) {
0062
          ok = 0;
0063
          str = WtNewString("Invalid object.");
0064
          Tcl_IncrRefCount(str);
0065
          WtAddError(NULL, str, interp, w);
0066
          break;
0067
        }
0068
0069
        WtLog(HERE, APLOG_DEBUG | APLOG_NOERRNO, w,
0070
          "WtEvalEventHandlers: Handling \"%s\" event. Evaluating: "
0071
          "\"%s\".", name, WtToString(script));
0072
0073
        if (Tcl_EvalObj(interp, script) != TCL_OK) {
0074
          status = WT_STATUS_ERROR;
0075
          eventStatus = WT_STATUS_ERROR;
0076
          snprintf(errMsg, sizeof(errMsg), "\n    (\"%s\" script #%d)",
0077
            name, i + 1);
0078
          Tcl_AddObjErrorInfo(interp, errMsg, -1);
0079
          WtAddEvalError(interp, w);
0080
        } else {
0081
          status = WT_STATUS_OK;
0082
        }
0083
0084
        WtLog(HERE, APLOG_DEBUG | APLOG_NOERRNO, w,
0085
          "WtEvalEventHandlers: Script status: %d.", status);
0086
0087
        /* Update the status */
0088
0089
        isNewHandler = WtCopyOnWrite(&handler);
0090
        WtTableSetStrToInt(handler, "status", status);
0091
0092
        isNewList = WtCopyOnWrite(&list);
0093
        Tcl_IncrRefCount(handler);
0094
0095
        if (Tcl_ListObjReplace(interp, list, i, 1, 1, &handler) != TCL_OK) {
0096
          ok = 0;
0097
          WtAddInterpError(interp, w);
0098
        } else {
0099
          isNewTable = WtCopyOnWrite(tablePtr);
0100
          WtTableSetStrToObj(*tablePtr, name, list);
0101
        }
0102
0103
        Tcl_DecrRefCount(handler);
0104
0105
        if (isNewHandler) {
0106
          Tcl_DecrRefCount(handler);
0107
        }
0108
0109
        if (isNewList) {
0110
          Tcl_DecrRefCount(list);
0111
        }
0112
0113
        if (!ok) {
0114
          break;
0115
        }
0116
0117
        list = WtTableGetObjFromStr(*tablePtr, name, NULL);
0118
      }
0119
    }
0120
  }
0121
0122
  if (eventStatus != WT_STATUS_OK) {
0123
    ok = 0;
0124
  }
0125
0126
  if (errorSetId != -1) {
0127
    if (WtStopErrors(w, interp, errorSetId, 1) == -1) {
0128
      ok = 0;
0129
    }
0130
  }
0131
0132
  return ok;
0133
}
0134
0135
/* events command */
0136
0137
int WtContextEventsCmd(ClientData clientData, Tcl_Interp *interp,
0138
    int objc, Tcl_Obj *const objv[])
0139
{
0140
  int ret = TCL_ERROR;
0141
  WtContext *w = WtGetAssocContext(interp);
0142
  char *subCmd;
0143
0144
  if (objc < 2) {
0145
    WtContextEventsUsage(interp, objv[0]);
0146
  } else {
0147
    subCmd = Tcl_GetString(objv[1]);
0148
0149
    if (!strcmp(subCmd, "items")) {
0150
      ret = WtCtxEvtItemsCmd(clientData, interp, objc, objv);
0151
    } else if (!strcmp(subCmd, "add")) {
0152
      ret = WtCtxEvtAddCmd(clientData, interp, objc, objv);
0153
    } else if (!strcmp(subCmd, "remove")) {
0154
      ret = WtCtxEvtRemoveCmd(clientData, interp, objc, objv);
0155
    } else if (!strcmp(subCmd, "fire")) {
0156
      ret = WtCtxEvtFireCmd(clientData, interp, objc, objv);
0157
    } else if (!strcmp(subCmd, "handlers")) {
0158
      ret = WtCtxEvtHandlersCmd(clientData, interp, objc, objv);
0159
    } else if (!strcmp(subCmd, "addHandler")) {
0160
      ret = WtCtxEvtAddHandlerCmd(clientData, interp, objc, objv);
0161
    } else if (!strcmp(subCmd, "removeHandler")) {
0162
      ret = WtCtxEvtRemoveHandlerCmd(clientData, interp, objc, objv);
0163
    } else {
0164
      WtContextEventsUsage(interp, objv[0]);
0165
    }
0166
  }
0167
0168
  return ret;
0169
}
0170
0171
/* items command */
0172
0173
int WtCtxEvtItemsCmd(ClientData clientData, Tcl_Interp *interp,
0174
    int objc, Tcl_Obj *const objv[])
0175
{
0176
  int ret = TCL_ERROR;
0177
  WtContext *w = WtGetAssocContext(interp);
0178
0179
  if (objc == 2) {
0180
    Tcl_SetObjResult(interp, w->web->ctxEventHandlers);
0181
    ret = TCL_OK;
0182
  } else if (objc == 3) {
0183
    WtSetObj(&w->web->ctxEventHandlers, objv[2]);
0184
    ret = TCL_OK;
0185
  } else {
0186
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0187
      WtToString(objv[0]), " ", WtToString(objv[1]),
0188
      " ?newItems?", NULL);
0189
  }
0190
0191
  return ret;
0192
}
0193
0194
/* add command */
0195
0196
int WtCtxEvtAddCmd(ClientData clientData, Tcl_Interp *interp,
0197
    int objc, Tcl_Obj *const objv[])
0198
{
0199
  int ret = TCL_ERROR;
0200
  Tcl_Obj *list;
0201
  WtContext *w = WtGetAssocContext(interp);
0202
0203
  if (objc == 3) {
0204
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0205
      list = Tcl_NewListObj(0, NULL);
0206
      WtTableSet(w->web->ctxEventHandlers, objv[2], list);
0207
      ret = TCL_OK;
0208
    }
0209
  } else {
0210
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0211
      WtToString(objv[0]), " ", WtToString(objv[1]),
0212
      " eventName", NULL);
0213
  }
0214
0215
  return ret;
0216
}
0217
0218
/* remove command */
0219
0220
int WtCtxEvtRemoveCmd(ClientData clientData, Tcl_Interp *interp,
0221
    int objc, Tcl_Obj *const objv[])
0222
{
0223
  int ret = TCL_ERROR;
0224
  WtContext *w = WtGetAssocContext(interp);
0225
0226
  if (objc == 3) {
0227
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0228
      WtTableRemove(w->web->ctxEventHandlers, objv[2]);
0229
      ret = TCL_OK;
0230
    }
0231
  } else {
0232
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0233
      WtToString(objv[0]), " ", WtToString(objv[1]),
0234
      " eventName", NULL);
0235
  }
0236
0237
  return ret;
0238
}
0239
0240
/* fire command */
0241
0242
int WtCtxEvtFireCmd(ClientData clientData, Tcl_Interp *interp,
0243
    int objc, Tcl_Obj *const objv[])
0244
{
0245
  int ret = TCL_ERROR;
0246
0247
  if (objc == 3) {
0248
    Tcl_AppendResult(interp, "Not implemented.", NULL);
0249
  } else {
0250
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0251
      WtToString(objv[0]), " ", WtToString(objv[1]),
0252
      " eventName", NULL);
0253
  }
0254
0255
  return ret;
0256
}
0257
0258
/* handlers command */
0259
0260
int WtCtxEvtHandlersCmd(ClientData clientData, Tcl_Interp *interp,
0261
    int objc, Tcl_Obj *const objv[])
0262
{
0263
  int ret = TCL_ERROR;
0264
  Tcl_Obj *list;
0265
  WtContext *w = WtGetAssocContext(interp);
0266
0267
  if (objc == 4) {
0268
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0269
      WtTableSet(w->web->ctxEventHandlers, objv[2], objv[3]);
0270
      ret = TCL_OK;
0271
    }
0272
  } else if (objc == 3) {
0273
    list = WtTableGet(w->web->ctxEventHandlers, objv[2]);
0274
    Tcl_SetObjResult(interp, list ? list : Tcl_NewListObj(0, NULL));
0275
    ret = TCL_OK;
0276
  } else {
0277
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0278
      WtToString(objv[0]), " ", WtToString(objv[1]),
0279
      " eventName ?handlers?", NULL);
0280
  }
0281
0282
  return ret;
0283
}
0284
0285
/* addHandler command */
0286
0287
int WtCtxEvtAddHandlerCmd(ClientData clientData, Tcl_Interp *interp,
0288
    int objc, Tcl_Obj *const objv[])
0289
{
0290
  int ret = TCL_ERROR;
0291
  Tcl_Obj *hook;
0292
  WtContext *w = WtGetAssocContext(interp);
0293
0294
  if (objc == 4) {
0295
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0296
      hook = WtNewTableObj();
0297
      Tcl_IncrRefCount(hook);
0298
      WtTableSetStrToObj(hook, "script", objv[3]);
0299
      WtTableSetStrToInt(hook, "status", WT_STATUS_NONE);
0300
0301
      if (WtTableAppendToList(w->web->ctxEventHandlers,
0302
          objv[2], hook, NULL, interp)) {
0303
        ret = TCL_OK;
0304
      }
0305
0306
      Tcl_DecrRefCount(hook);
0307
    }
0308
  } else {
0309
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0310
      WtToString(objv[0]), " ", WtToString(objv[1]),
0311
      " eventName handler", NULL);
0312
  }
0313
0314
  return ret;
0315
}
0316
0317
/* removeHandler command */
0318
0319
int WtCtxEvtRemoveHandlerCmd(ClientData clientData, Tcl_Interp *interp,
0320
    int objc, Tcl_Obj *const objv[])
0321
{
0322
  int ret = TCL_ERROR, len, i;
0323
  Tcl_Obj *list, *elem;
0324
  WtContext *w = WtGetAssocContext(interp);
0325
0326
  if (objc == 4) {
0327
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0328
      list = WtTableGet(w->web->ctxEventHandlers, objv[2]);
0329
      if (Tcl_ListObjLength(interp, list, &len) == TCL_OK) {
0330
        ret = TCL_OK;
0331
        for (i = len; i >= 0; --i) {
0332
          if (Tcl_ListObjIndex(interp, list, i, &elem) != TCL_OK) {
0333
            ret = TCL_ERROR;
0334
            break;
0335
          }
0336
          if (!strcmp(WtToString(elem), WtToString(objv[3]))) {
0337
            if (Tcl_ListObjReplace(interp, list, i, 1, 0, NULL) != TCL_OK) {
0338
              ret = TCL_ERROR;
0339
              break;
0340
            }
0341
          }
0342
        }
0343
      }
0344
    }
0345
  } else {
0346
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0347
      WtToString(objv[0]), " ", WtToString(objv[1]),
0348
      " eventName handler", NULL);
0349
  }
0350
0351
  return ret;
0352
}
0353
0354
void WtContextEventsUsage(Tcl_Interp *interp, Tcl_Obj *cmd)
0355
{
0356
  char *cmdStr = WtToString(cmd);
0357
0358
  Tcl_AppendResult(interp,
0359
    wtBadUsagePrefix2,
0360
    cmdStr, " items\n",
0361
    cmdStr, " add eventName\n",
0362
    cmdStr, " remove eventName\n",
0363
    cmdStr, " fire eventName\n",
0364
    cmdStr, " handlers eventName ?handlers?\n",
0365
    cmdStr, " addHandler eventName handler\n",
0366
    cmdStr, " removeHandler eventName handler\n",
0367
    NULL);
0368
}
0369
0370
/* Init event handler scripts */
0371
0372
int WtInitCtxEventHandlers(WtContext *w, Tcl_Interp *interp)
0373
{
0374
  int ok = 1, len, i;
0375
  Tcl_HashTable *hashTable;
0376
  Tcl_HashEntry *ent;
0377
  Tcl_HashSearch search;
0378
  Tcl_Obj *key, *list, *hooks, *hook, *item;
0379
  WtWebContext *web = w->web;
0380
0381
  if (!web) {
0382
    return 0;
0383
  }
0384
0385
  if (!web->ctxEventHandlers) {
0386
    WtSetObj(&web->ctxEventHandlers, WtNewTableObj());
0387
  }
0388
0389
  if (!WtConvertToTable(web->taskSettings, interp)) {
0390
    WtAddInterpError(interp, w);
0391
    ok = 0;
0392
  } else {
0393
    hooks = WtTableGetObjFromStr(web->taskSettings,
0394
      "server.ctxEventHandlers", NULL);
0395
0396
    if (hooks) {
0397
      hashTable = WtGetTableMap(hooks);
0398
      ent = Tcl_FirstHashEntry(hashTable, &search);
0399
0400
      while (ent) {
0401
        key = (Tcl_Obj *)Tcl_GetHashKey(hashTable, ent);
0402
        list = (Tcl_Obj *)Tcl_GetHashValue(ent);
0403
0404
        if (Tcl_ListObjLength(interp, list, &len) != TCL_OK) {
0405
          WtAddInterpError(interp, w);
0406
          ok = 0;
0407
          break;
0408
        }
0409
0410
        for (i = 0; i < len; i++) {
0411
          if (Tcl_ListObjIndex(interp, list, i, &item) != TCL_OK) {
0412
            WtAddInterpError(interp, w);
0413
            ok = 0;
0414
            break;
0415
          }
0416
0417
          hook = WtNewTableObj();
0418
0419
          WtTableSetStrToObj(hook, "script",
0420
            WtTableGetObjFromStr(item, "script", NULL));
0421
0422
          WtTableSetStrToInt(hook, "status", WT_STATUS_NONE);
0423
0424
          if (!WtTableAppendToList(web->ctxEventHandlers,
0425
              key, hook, NULL, interp)) {
0426
            WtAddInterpError(interp, w);
0427
            ok = 0;
0428
            break;
0429
          }
0430
        }
0431
0432
        if (!ok) {
0433
          break;
0434
        }
0435
0436
        ent = Tcl_NextHashEntry(&search);
0437
      }
0438
    }
0439
  }
0440
0441
  return ok;
0442
}
0443
0444
int WtAtEndCmd(ClientData clientData, Tcl_Interp *interp,
0445
    int objc, Tcl_Obj *const objv[])
0446
{
0447
  int ret = TCL_ERROR;
0448
  Tcl_Obj *key, *hook;
0449
  WtContext *w = WtGetAssocContext(interp);
0450
0451
  if (objc == 2) {
0452
    if (WtOwnTable(&w->web->ctxEventHandlers, interp)) {
0453
      key = WtNewString("endRequest");
0454
      Tcl_IncrRefCount(key);
0455
0456
      hook = WtNewTableObj();
0457
      Tcl_IncrRefCount(hook);
0458
      WtTableSetStrToObj(hook, "script", objv[1]);
0459
      WtTableSetStrToInt(hook, "status", WT_STATUS_NONE);
0460
0461
      if (WtTableAppendToList(w->web->ctxEventHandlers,
0462
          key, hook, NULL, interp)) {
0463
        ret = TCL_OK;
0464
      }
0465
0466
      Tcl_DecrRefCount(hook);
0467
      Tcl_DecrRefCount(key);
0468
    }
0469
  } else {
0470
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0471
      WtToString(objv[0]), " ", WtToString(objv[1]),
0472
      " script", NULL);
0473
  }
0474
0475
  return ret;
0476
}