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 / WtProcSession.c

Lines Size Modified Created Owner MIME Types
1,234 29,648 2010/05/09 03:50:10 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 "WtProcSession.h"
0018
#include "WtUtil.h"
0019
#include "WtTable.h"
0020
#include "WtTableUtil.h"
0021
0022
Tcl_HashTable wtPSTables;
0023
Tcl_Mutex wtPSTablesLock = NULL;
0024
0025
/* Get the session ID */
0026
0027
Tcl_Obj *WtGetProcSessionId(WtProcSession *sh, Tcl_Interp *interp)
0028
{
0029
  return sh->id;
0030
}
0031
0032
/* Open the session */
0033
0034
int WtOpenProcSession(WtProcSession *sh, Tcl_Obj *id, Tcl_Interp *interp)
0035
{
0036
  int ok = 1;
0037
  Tcl_Obj *curId;
0038
0039
  if (!Tcl_GetCharLength(id)) {
0040
    Tcl_AppendResult(interp, "Session ID string is invalid.", NULL);
0041
    ok = 0;
0042
  } else {
0043
    curId = WtGetProcSessionId(sh, interp);
0044
    if (!curId || strcmp(WtToString(curId), WtToString(id))) {
0045
      if (sh->psTable && !WtCloseProcSession(sh, interp)) {
0046
        ok = 0;
0047
      } else if (!WtOpenProcSessionTable(sh, id, interp)) {
0048
        ok = 0;
0049
      }
0050
    }
0051
  }
0052
0053
  return ok;
0054
}
0055
0056
/* Close the session */
0057
0058
int WtCloseProcSession(WtProcSession *sh, Tcl_Interp *interp)
0059
{
0060
  int ok = 1;
0061
0062
  if (sh->psTable) {
0063
    if (!WtCloseProcSessionTable(sh, interp)) {
0064
      ok = 0;
0065
    }
0066
  }
0067
0068
  return ok;
0069
}
0070
0071
/* Initialize the session */
0072
0073
int WtInitProcSession(WtProcSession *sh, Tcl_Interp *interp)
0074
{
0075
  int ok = 1;
0076
  WtSession *s;
0077
  Tcl_Obj *id;
0078
0079
  if (!sh->initDone) {
0080
    if (!sh->psTable) {
0081
      s = WtGetAssocSession(interp);
0082
      if (!(id = WtGetInitialSessionId(s, NULL, interp))) {
0083
        ok = 0;
0084
      } else if (!WtOpenProcSession(sh, id, interp)) {
0085
        ok = 0;
0086
      } else {
0087
        sh->initDone = 1;
0088
      }
0089
    }
0090
  } else if (!sh->psTable) {
0091
    Tcl_AppendResult(interp, "Session not open.", NULL);
0092
    ok = 0;
0093
  }
0094
0095
  return ok;
0096
}
0097
0098
/* Open the session table storage */
0099
0100
int WtOpenProcSessionTable(WtProcSession *sh, Tcl_Obj *id,
0101
    Tcl_Interp *interp)
0102
{
0103
  int ok = 1, created = 0;
0104
  Tcl_HashEntry *ent;
0105
  WtPSTable *st;
0106
0107
  if (sh->psTable && !WtCloseProcSessionTable(sh, interp)) {
0108
    ok = 0;
0109
  } else {
0110
    Tcl_MutexLock(&wtPSTablesLock);
0111
    ent = Tcl_CreateHashEntry(&wtPSTables,
0112
      (char *)id, &created);
0113
    if (!ent) {
0114
      ok = 0;
0115
    } else {
0116
      if (!created) {
0117
        sh->psTable = (Tcl_Obj *)Tcl_GetHashValue(ent);
0118
        st = WtPSTableRep(sh->psTable);
0119
      } else if (sh->psTable = WtNewPSTableObj()) {
0120
        /*
0121
        st = WtPSTableRep(sh->psTable);
0122
        st->id = WtNewString(Tcl_GetString(id));
0123
        Tcl_IncrRefCount(st->id);
0124
        */
0125
        Tcl_IncrRefCount(sh->psTable);
0126
        Tcl_SetHashValue(ent, sh->psTable);
0127
        sh->isNew = 1;
0128
      }
0129
0130
      if (!sh->psTable) {
0131
        ok = 0;
0132
      } else {
0133
        sh->id = WtNewString(Tcl_GetString(id));
0134
        Tcl_IncrRefCount(sh->id);
0135
        st = WtPSTableRep(sh->psTable);
0136
        st->accessTime = time(NULL);
0137
        Tcl_IncrRefCount(sh->psTable);
0138
      }
0139
    }
0140
    Tcl_MutexUnlock(&wtPSTablesLock);
0141
  }
0142
0143
  return ok;
0144
}
0145
0146
/* Close the session table */
0147
0148
int WtCloseProcSessionTable(WtProcSession *sh, Tcl_Interp *interp)
0149
{
0150
  int ok = 1;
0151
0152
  if (sh->id || sh->psTable) {
0153
    if (sh->id) {
0154
      Tcl_DecrRefCount(sh->id);
0155
      sh->id = NULL;
0156
    }
0157
0158
    if (sh->psTable) {
0159
      // WtPSTableRep(sh->psTable)->accessTime = time(NULL);
0160
      Tcl_DecrRefCount(sh->psTable);
0161
      sh->psTable = NULL;
0162
    }
0163
0164
    sh->isNew = 0;
0165
    sh->isModified = 0;
0166
  }
0167
0168
  return ok;
0169
}
0170
0171
/* Find a session table */
0172
0173
Tcl_Obj *WtGetProcSessionTable(Tcl_Obj *id)
0174
{
0175
  Tcl_Obj *psTable = NULL;
0176
  Tcl_HashEntry *ent;
0177
0178
  Tcl_MutexLock(&wtPSTablesLock);
0179
  ent = Tcl_FindHashEntry(&wtPSTables, (char *)id);
0180
  if (ent) {
0181
    psTable = (Tcl_Obj *)Tcl_GetHashValue(ent);
0182
  }
0183
  Tcl_MutexUnlock(&wtPSTablesLock);
0184
0185
  return psTable;
0186
}
0187
0188
/* Status of a process session table */
0189
0190
WtSessionStatus WtGetPSTableStatus(Tcl_Obj *stObj, Tcl_Interp *interp)
0191
{
0192
  WtPSTable *st;
0193
  WtSessionStatus status;
0194
  WtSession *s;
0195
0196
  if (!stObj) {
0197
    status = WT_SESSION_STATUS_INVALID;
0198
  } else {
0199
    st = WtPSTableRep(stObj);
0200
    s = WtGetAssocSession(interp);
0201
    if (time(NULL) - st->accessTime >= s->maxIdleTime) {
0202
      status = WT_SESSION_STATUS_EXPIRED;
0203
    } else {
0204
      status = WT_SESSION_STATUS_ACTIVE;
0205
    }
0206
  }
0207
0208
  return status;
0209
}
0210
0211
/* Delete a session */
0212
0213
int WtDeleteProcSession(WtProcSession *sh, Tcl_Obj *id, Tcl_Interp *interp)
0214
{
0215
  int ok = 1, deleteSelf = 0;
0216
  Tcl_Obj *psTable;
0217
  Tcl_HashEntry *ent;
0218
0219
  if (id) {
0220
    if (!Tcl_GetCharLength(id)) {
0221
      Tcl_AppendResult(interp, "Session ID string is invalid.", NULL);
0222
      ok = 0;
0223
    }
0224
  } else if (!WtInitProcSession(sh, interp)) {
0225
    ok = 0;
0226
  } else if (!(id = WtGetProcSessionId(sh, interp))) {
0227
    ok = 0;
0228
  }
0229
0230
  if (ok) {
0231
    Tcl_MutexLock(&wtPSTablesLock);
0232
    ent = Tcl_FindHashEntry(&wtPSTables, (char *)id);
0233
    if (ent) {
0234
      psTable = (Tcl_Obj *)Tcl_GetHashValue(ent);
0235
      if (sh->psTable == psTable) {
0236
        deleteSelf = 1;
0237
      }
0238
      if (psTable) {
0239
        Tcl_DecrRefCount(psTable);
0240
      }
0241
      Tcl_DeleteHashEntry(ent);
0242
    }
0243
    Tcl_MutexUnlock(&wtPSTablesLock);
0244
0245
    if (deleteSelf && !WtCloseProcSession(sh, interp)) {
0246
      ok = 0;
0247
    }
0248
  }
0249
0250
  return ok;
0251
}
0252
0253
/* Delete stale sessions */
0254
0255
int WtSweepProcSessions(WtProcSession *sh, Tcl_Interp *interp)
0256
{
0257
  int ok = 1;
0258
  Tcl_HashSearch search;
0259
  Tcl_HashEntry *ent;
0260
  Tcl_Obj *val;
0261
  WtPSTable *st;
0262
  time_t maxTime;
0263
  WtSession *s = WtGetAssocSession(interp);
0264
0265
  if (s->maxIdleTime > 0) {
0266
    maxTime = time(NULL) + s->maxIdleTime;
0267
    Tcl_MutexLock(&wtPSTablesLock);
0268
    ent = Tcl_FirstHashEntry(&wtPSTables, &search);
0269
    while (ent) {
0270
      val = (Tcl_Obj *)Tcl_GetHashValue(ent);
0271
      if (val) {
0272
        st = WtPSTableRep(val);
0273
        if (st->accessTime <= maxTime) {
0274
          Tcl_DecrRefCount(val);
0275
          Tcl_DeleteHashEntry(ent);
0276
        }
0277
      }
0278
      ent = Tcl_NextHashEntry(&search);
0279
    }
0280
    Tcl_MutexUnlock(&wtPSTablesLock);
0281
  }
0282
0283
  return ok;
0284
}
0285
0286
/* Finalize request */
0287
0288
int WtProcSessionFinalizeRequest(WtProcSession *sh, Tcl_Interp *interp)
0289
{
0290
  int ok = 1;
0291
  Tcl_Obj *id;
0292
  WtSession *s = WtGetAssocSession(interp);
0293
0294
  if (!WtInitProcSession(sh, interp)) {
0295
    ok = 0;
0296
  } else if (id = WtGetProcSessionId(sh, interp)) {
0297
    if (!WtSetSessionCookie(s, id, interp, s->clientTimeStamp)) {
0298
      ok = 0;
0299
    }
0300
  }
0301
0302
  if (WtShouldSweepSessions(s, interp) &&
0303
      !WtSweepProcSessions(sh, interp)) {
0304
    ok = 0;
0305
  }
0306
0307
  return ok;
0308
}
0309
0310
/* Session command */
0311
0312
int WtProcSessionCmd(ClientData clientData, Tcl_Interp *interp,
0313
    int objc, Tcl_Obj *const objv[])
0314
{
0315
  WtSession *s = WtGetAssocSession(interp);
0316
  WtProcSession *sh;
0317
0318
  /* Initialize the session */
0319
0320
  if (!s->procSession) {
0321
    s->procSession = WtNewProcSessionObj();
0322
  }
0323
  sh = WtProcSessionRep(s->procSession);
0324
  return WtProcSessionCmdHelper(clientData, interp,
0325
    sh, objc, objv);
0326
}
0327
0328
/* Session command helper */
0329
0330
int WtProcSessionCmdHelper(ClientData clientData, Tcl_Interp *interp,
0331
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0332
{
0333
  int ret = TCL_ERROR;
0334
  char *subCmd;
0335
0336
  if (objc < 2) {
0337
    WtProcSessionCmdUsage(interp, objv[0]);
0338
    return ret;
0339
  }
0340
0341
  subCmd = Tcl_GetString(objv[1]);
0342
0343
  if (!strcmp(subCmd, "id")) {
0344
    ret = WtProcSessionIdCmd(clientData, interp, sh, objc, objv);
0345
  } else if (!strcmp(subCmd, "count")) {
0346
    ret = WtProcSessionCountCmd(clientData, interp, sh, objc, objv);
0347
  } else if (!strcmp(subCmd, "has")) {
0348
    ret = WtProcSessionHasCmd(clientData, interp, sh, objc, objv);
0349
  } else if (!strcmp(subCmd, "get")) {
0350
    ret = WtProcSessionGetCmd(clientData, interp, sh, objc, objv);
0351
  } else if (!strcmp(subCmd, "set")) {
0352
    ret = WtProcSessionSetCmd(clientData, interp, sh, objc, objv);
0353
  } else if (!strcmp(subCmd, "setDefault")) {
0354
    ret = WtProcSessionSetDefaultCmd(clientData, interp, sh, objc, objv);
0355
  } else if (!strcmp(subCmd, "keys")) {
0356
    ret = WtProcSessionKeysCmd(clientData, interp, sh, objc, objv);
0357
  } else if (!strcmp(subCmd, "values")) {
0358
    ret = WtProcSessionValuesCmd(clientData, interp, sh, objc, objv);
0359
  } else if (!strcmp(subCmd, "remove")) {
0360
    ret = WtProcSessionRemoveCmd(clientData, interp, sh, objc, objv);
0361
  } else if (!strcmp(subCmd, "removeList")) {
0362
    ret = WtProcSessionRemoveListCmd(clientData, interp, sh, objc, objv);
0363
  } else if (!strcmp(subCmd, "array")) {
0364
    ret = WtProcSessionArrayCmd(clientData, interp, sh, objc, objv);
0365
  } else if (!strcmp(subCmd, "items")) {
0366
    ret = WtProcSessionItemsCmd(clientData, interp, sh, objc, objv);
0367
  } else if (!strcmp(subCmd, "touch")) {
0368
    ret = WtProcSessionTouchCmd(clientData, interp, sh, objc, objv);
0369
  } else if (!strcmp(subCmd, "clear")) {
0370
    ret = WtProcSessionClearCmd(clientData, interp, sh, objc, objv);
0371
  } else if (!strcmp(subCmd, "isAccessed")) {
0372
    ret = WtProcSessionIsAccessedCmd(clientData, interp, sh, objc, objv);
0373
  } else if (!strcmp(subCmd, "isModified")) {
0374
    ret = WtProcSessionIsModifiedCmd(clientData, interp, sh, objc, objv);
0375
  } else if (!strcmp(subCmd, "status")) {
0376
    ret = WtProcSessionStatusCmd(clientData, interp, sh, objc, objv);
0377
  } else if (!strcmp(subCmd, "properties")) {
0378
    ret = WtProcSessionPropertiesCmd(clientData, interp, sh, objc, objv);
0379
  } else if (!strcmp(subCmd, "clientProperties")) {
0380
    ret = WtProcSessionClientPropertiesCmd(clientData, interp, sh, objc,
0381
      objv);
0382
  } else if (!strcmp(subCmd, "delete")) {
0383
    ret = WtProcSessionDeleteCmd(clientData, interp, sh, objc, objv);
0384
  } else if (!strcmp(subCmd, "sweep")) {
0385
    ret = WtProcSessionSweepCmd(clientData, interp, sh, objc, objv);
0386
  } else if (!strcmp(subCmd, "unload")) {
0387
    ret = WtProcSessionUnloadCmd(clientData, interp, sh, objc, objv);
0388
  } else if (!strcmp(subCmd, "loadModule")) {
0389
    ret = WtProcSessionLoadModuleCmd(clientData, interp, sh, objc, objv);
0390
  } else if (!strcmp(subCmd, "unloadModule")) {
0391
    ret = WtProcSessionUnloadModuleCmd(clientData, interp, sh, objc, objv);
0392
  } else if (!strcmp(subCmd, "finalizeRequest")) {
0393
    ret = WtProcSessionFinalizeCmd(clientData, interp, sh, objc, objv);
0394
  } else {
0395
    WtProcSessionCmdUsage(interp, objv[0]);
0396
  }
0397
0398
  return ret;
0399
}
0400
0401
/* Session command usage */
0402
0403
void WtProcSessionCmdUsage(Tcl_Interp *interp, Tcl_Obj *cmd)
0404
{
0405
  char *cmdStr = Tcl_GetString(cmd);
0406
0407
  Tcl_AppendResult(interp,
0408
    wtBadUsagePrefix2,
0409
    cmdStr, " id\n",
0410
    cmdStr, " count\n",
0411
    cmdStr, " has key\n",
0412
    cmdStr, " get key ?defaultValue?\n",
0413
    cmdStr, " set key value\n",
0414
    cmdStr, " setDefault key defaultValue\n",
0415
    cmdStr, " keys\n",
0416
    cmdStr, " values\n",
0417
    cmdStr, " remove key\n",
0418
    cmdStr, " removeList keys\n",
0419
    cmdStr, " array arrayName\n",
0420
    cmdStr, " items\n",
0421
    cmdStr, " touch\n",
0422
    cmdStr, " clear\n",
0423
    cmdStr, " isAccessed\n",
0424
    cmdStr, " isModified\n",
0425
    cmdStr, " status ?id?\n",
0426
    cmdStr, " properties ?id?\n",
0427
    cmdStr, " delete ?id?\n",
0428
    cmdStr, " sweep\n",
0429
    cmdStr, " unload\n",
0430
    cmdStr, " loadModule\n",
0431
    cmdStr, " unloadModule\n",
0432
    cmdStr, " finalizeRequest\n",
0433
    NULL);
0434
}
0435
0436
/* id command */
0437
0438
int WtProcSessionIdCmd(ClientData clientData, Tcl_Interp *interp,
0439
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0440
{
0441
  int ret = TCL_ERROR;
0442
  Tcl_Obj *id;
0443
0444
  if (objc == 2) {
0445
    if (WtInitProcSession(sh, interp) && 
0446
        (id = WtGetProcSessionId(sh, interp))) {
0447
      Tcl_SetObjResult(interp, id ? id : WtNewString(NULL));
0448
      ret = TCL_OK;
0449
    }
0450
  } else if (objc == 3) {
0451
    if (WtOpenProcSession(sh, objv[2], interp)) {
0452
      ret = TCL_OK;
0453
    }
0454
  } else {
0455
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0456
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0457
  }
0458
0459
  return ret;
0460
}
0461
0462
/* count command */
0463
0464
int WtProcSessionCountCmd(ClientData clientData, Tcl_Interp *interp,
0465
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0466
{
0467
  int ret = TCL_ERROR;
0468
  Tcl_Obj *mt;
0469
0470
  if (objc == 2) {
0471
    if (mt = WtGetPSStorage(sh, interp)) {
0472
      Tcl_SetObjResult(interp, Tcl_NewIntObj(WtMtTableSize(mt)));
0473
      ret = TCL_OK;
0474
    }
0475
  } else {
0476
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0477
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0478
  }
0479
0480
  return ret;
0481
}
0482
0483
/* has command */
0484
0485
int WtProcSessionHasCmd(ClientData clientData, Tcl_Interp *interp,
0486
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0487
{
0488
  int ret = TCL_ERROR;
0489
  Tcl_Obj *mt;
0490
0491
  if (objc == 3) {
0492
    if (mt = WtGetPSStorage(sh, interp)) {
0493
      Tcl_SetObjResult(interp,
0494
        Tcl_NewBooleanObj(WtMtTableHas(mt, objv[2])));
0495
      ret = TCL_OK;
0496
    }
0497
  } else {
0498
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0499
      WtToString(objv[0]), " ", WtToString(objv[1]), " key", NULL);
0500
  }
0501
0502
  return ret;
0503
}
0504
0505
/* get command */
0506
0507
int WtProcSessionGetCmd(ClientData clientData, Tcl_Interp *interp,
0508
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0509
{
0510
  int ret = TCL_ERROR;
0511
  Tcl_Obj *mt, *obj;
0512
  
0513
  if (objc == 3 || objc == 4) {
0514
    if (mt = WtGetPSStorage(sh, interp)) {
0515
      obj = WtMtTableGet(mt, objv[2]);
0516
      if (obj) {
0517
        Tcl_SetObjResult(interp, obj);
0518
        ret = TCL_OK;
0519
      } else if (objc > 3) {
0520
        Tcl_SetObjResult(interp, objv[3]);
0521
        ret = TCL_OK;
0522
      } else {
0523
        Tcl_AppendResult(interp,
0524
          "No entry with key \"", Tcl_GetString(objv[2]),
0525
          "\" exists, and no default value was specified.", NULL);
0526
      }
0527
    }
0528
  }
0529
0530
  return ret;
0531
}
0532
0533
/* set command */
0534
0535
int WtProcSessionSetCmd(ClientData clientData, Tcl_Interp *interp,
0536
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0537
{
0538
  int ret = TCL_ERROR;
0539
  Tcl_Obj *mt;
0540
0541
  if (objc == 4) {
0542
    if (mt = WtGetPSStorage(sh, interp)) {
0543
      WtMtTableSet(mt, objv[2], objv[3]);
0544
      Tcl_SetObjResult(interp, objv[3]);
0545
      ret = TCL_OK;
0546
    }
0547
  } else {
0548
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0549
      WtToString(objv[0]), " ", WtToString(objv[1]),
0550
      " key value", NULL);
0551
  }
0552
0553
  return ret;
0554
}
0555
0556
/* setDefault command */
0557
0558
int WtProcSessionSetDefaultCmd(ClientData clientData, Tcl_Interp *interp,
0559
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0560
{
0561
  int ret = TCL_ERROR;
0562
  Tcl_Obj *mt, *obj;
0563
0564
  if (objc == 4) {
0565
    if (mt = WtGetPSStorage(sh, interp)) {
0566
      obj = WtMtTableGet(mt, objv[2]);
0567
      if (obj) {
0568
        Tcl_SetObjResult(interp, obj);
0569
      } else {
0570
        WtMtTableSet(mt, objv[2], objv[3]);
0571
      }
0572
      ret = TCL_OK;
0573
    }
0574
  } else {
0575
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0576
      WtToString(objv[0]), " ", WtToString(objv[1]),
0577
      " key value", NULL);
0578
  }
0579
0580
  return ret;
0581
}
0582
0583
/* keys command */
0584
0585
int WtProcSessionKeysCmd(ClientData clientData, Tcl_Interp *interp,
0586
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0587
{
0588
  int ret = TCL_ERROR;
0589
  Tcl_Obj *mt, *keys;
0590
0591
  if (objc == 2) {
0592
    if (mt = WtGetPSStorage(sh, interp)) {
0593
      if (WtMtTableKeys(mt, &keys, interp)) {
0594
        Tcl_SetObjResult(interp, keys);
0595
        ret = TCL_OK;
0596
      }
0597
    }
0598
  } else {
0599
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0600
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0601
  }
0602
0603
  return ret;
0604
}
0605
0606
/* values command */
0607
0608
int WtProcSessionValuesCmd(ClientData clientData, Tcl_Interp *interp,
0609
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0610
{
0611
  int ret = TCL_ERROR;
0612
  Tcl_Obj *mt, *vals;
0613
0614
  if (objc == 2) {
0615
    if (mt = WtGetPSStorage(sh, interp)) {
0616
      if (WtMtTableValues(mt, &vals, interp)) {
0617
        Tcl_SetObjResult(interp, vals);
0618
        ret = TCL_OK;
0619
      }
0620
    }
0621
  } else {
0622
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0623
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0624
  }
0625
0626
  return ret;
0627
}
0628
0629
/* remove command */
0630
0631
int WtProcSessionRemoveCmd(ClientData clientData, Tcl_Interp *interp,
0632
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0633
{
0634
  int ret = TCL_ERROR;
0635
  Tcl_Obj *mt;
0636
0637
  if (objc == 3) {
0638
    if (mt = WtGetPSStorage(sh, interp)) {
0639
      WtMtTableRemove(mt, objv[2]);
0640
      ret = TCL_OK;
0641
    }
0642
  } else {
0643
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0644
      WtToString(objv[0]), " ", WtToString(objv[1]), " key", NULL);
0645
  }
0646
0647
  return ret;
0648
}
0649
0650
/* removeList command */
0651
0652
int WtProcSessionRemoveListCmd(ClientData clientData, Tcl_Interp *interp,
0653
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0654
{
0655
  int ret = TCL_ERROR;
0656
  Tcl_Obj *mt;
0657
0658
  if (objc == 3) {
0659
    if (mt = WtGetPSStorage(sh, interp)) {
0660
      if (WtMtTableRemoveList(mt, objv[2], interp)) {
0661
        ret = TCL_OK;
0662
      }
0663
    }
0664
  } else {
0665
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0666
      WtToString(objv[0]), " ", WtToString(objv[1]), " list", NULL);
0667
  }
0668
0669
  return ret;
0670
}
0671
0672
/* array command */
0673
0674
int WtProcSessionArrayCmd(ClientData clientData, Tcl_Interp *interp,
0675
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0676
{
0677
  int ret = TCL_ERROR;
0678
  Tcl_Obj *mt;
0679
0680
  if (objc == 3) {
0681
    if (mt = WtGetPSStorage(sh, interp)) {
0682
      WtMtTableLock(mt);
0683
      if (WtTableToArray(interp, WtMtTableRep(mt)->tbl, objv[2], 0)) {
0684
        ret = TCL_OK;
0685
      }
0686
      WtMtTableUnlock(mt);
0687
    }
0688
  } else {
0689
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0690
      WtToString(objv[0]), " ", WtToString(objv[1]), " arrayName",
0691
      NULL);
0692
  }
0693
0694
  return ret;
0695
}
0696
0697
/* items command */
0698
0699
int WtProcSessionItemsCmd(ClientData clientData, Tcl_Interp *interp,
0700
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0701
{
0702
  int ret = TCL_ERROR;
0703
  Tcl_Obj *mt, *tbl;
0704
0705
  if (objc == 2) {
0706
    if (mt = WtGetPSStorage(sh, interp)) {
0707
      WtMtTableLock(mt);
0708
      tbl = Tcl_DuplicateObj(WtMtTableStorage(mt));
0709
      Tcl_SetObjResult(interp, tbl);
0710
      WtMtTableUnlock(mt);
0711
      ret = TCL_OK;
0712
    }
0713
  } else {
0714
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0715
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0716
  }
0717
0718
  return ret;
0719
}
0720
0721
/* touch command */
0722
0723
int WtProcSessionTouchCmd(ClientData clientData, Tcl_Interp *interp,
0724
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0725
{
0726
  int ret = TCL_ERROR;
0727
0728
  if (objc == 2) {
0729
    if (WtInitProcSession(sh, interp) && sh->psTable) {
0730
      WtPSTableRep(sh->psTable)->accessTime = time(NULL);
0731
      ret = TCL_OK;
0732
    }
0733
  } else {
0734
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0735
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0736
  }
0737
0738
  return ret;
0739
}
0740
0741
/* clear command */
0742
0743
int WtProcSessionClearCmd(ClientData clientData, Tcl_Interp *interp,
0744
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0745
{
0746
  int ret = TCL_ERROR;
0747
  Tcl_Obj *mt;
0748
0749
  if (objc == 2) {
0750
    if (mt = WtGetPSStorage(sh, interp)) {
0751
      WtMtTableClear(mt);
0752
      ret = TCL_OK;
0753
    }
0754
  } else {
0755
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0756
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0757
  }
0758
0759
  return ret;
0760
}
0761
0762
/* isAccessed command */
0763
0764
int WtProcSessionIsAccessedCmd(ClientData clientData, Tcl_Interp *interp,
0765
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0766
{
0767
  int ret = TCL_ERROR;
0768
0769
  if (objc == 2) {
0770
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj((int)sh->psTable));
0771
    ret = TCL_OK;
0772
  } else {
0773
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0774
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0775
  }
0776
0777
  return ret;
0778
}
0779
0780
/* isModified command */
0781
0782
int WtProcSessionIsModifiedCmd(ClientData clientData, Tcl_Interp *interp,
0783
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0784
{
0785
  int ret = TCL_ERROR;
0786
0787
  if (objc == 2) {
0788
    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sh->isModified));
0789
    ret = TCL_OK;
0790
  } else {
0791
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0792
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0793
  }
0794
0795
  return ret;
0796
}
0797
0798
/* status command
0799
 *
0800
 * Result values: new, active, expired, invalid.
0801
 */
0802
0803
int WtProcSessionStatusCmd(ClientData clientData, Tcl_Interp *interp,
0804
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0805
{
0806
  int ret = TCL_OK;
0807
  Tcl_Obj *id = NULL, *st;
0808
  WtSessionStatus status;
0809
0810
  if (objc == 2 || objc == 3) {
0811
    if (objc == 3) {
0812
      id = objv[2];
0813
      st = WtGetProcSessionTable(id);
0814
      status = WtGetPSTableStatus(st, interp);
0815
    } else if (!WtInitProcSession(sh, interp)) {
0816
      ret = TCL_ERROR;
0817
    } else if (sh->isNew) {
0818
      status = WT_SESSION_STATUS_NEW;
0819
    } else {
0820
      status = WtGetPSTableStatus(sh->psTable, interp);
0821
    }
0822
0823
    if (ret == TCL_OK) {
0824
      Tcl_SetObjResult(interp, WtNewString(wtSessionStatusNames[status]));
0825
    }
0826
  } else {
0827
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0828
      WtToString(objv[0]), " ", WtToString(objv[1]),
0829
      " ?id?", NULL);
0830
    ret = TCL_ERROR;
0831
  }
0832
0833
  return ret;
0834
}
0835
0836
/* properties command */
0837
0838
int WtProcSessionPropertiesCmd(ClientData clientData, Tcl_Interp *interp,
0839
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0840
{
0841
  int ret = TCL_ERROR, self = 0;
0842
  Tcl_Obj *id = NULL, *stObj, *tbl;
0843
  WtSessionStatus status;
0844
  WtPSTable *st;
0845
0846
  if (objc == 2 || objc == 3) {
0847
    if (objc == 2) {
0848
      if (WtInitProcSession(sh, interp)) {
0849
        if (id = WtGetProcSessionId(sh, interp)) {
0850
          self = 1;
0851
        }
0852
      }
0853
    } else {
0854
      id = objv[2];
0855
    }
0856
0857
    if (id) {
0858
      stObj = WtGetProcSessionTable(id);
0859
      if (stObj) {
0860
        st = WtPSTableRep(stObj);
0861
        tbl = WtNewTableObj();
0862
        WtTableSetStrToObj(tbl, "id", id);
0863
        WtTableSetStrToLong(tbl, "accessTime", (long)st->accessTime);
0864
        WtTableSetStrToLong(tbl, "idleTime",
0865
          (long)(time(NULL) - st->accessTime));
0866
        WtTableSetStrToInt(tbl, "size", WtMtTableSize(st->sharedTable));
0867
      }
0868
0869
      if (self && sh->isNew) {
0870
        status = WT_SESSION_STATUS_NEW;
0871
      } else {
0872
        status = WtGetPSTableStatus(stObj, interp);
0873
      }
0874
      WtTableSetStrToStr(tbl, "status", wtSessionStatusNames[status]);
0875
0876
      Tcl_SetObjResult(interp, tbl);
0877
      ret = TCL_OK;
0878
    }
0879
  } else {
0880
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0881
      WtToString(objv[0]), " ", WtToString(objv[1]), " ?id?", NULL);
0882
  }
0883
0884
  return ret;
0885
}
0886
0887
/* clientProperties command */
0888
0889
int WtProcSessionClientPropertiesCmd(ClientData clientData,
0890
    Tcl_Interp *interp, WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0891
{
0892
  int ret = TCL_ERROR;
0893
  WtSession *s;
0894
  Tcl_Obj *tbl;
0895
0896
  if (objc == 2) {
0897
    s = WtGetAssocSession(interp);
0898
    tbl = WtNewTableObj();
0899
    WtTableSetStrToObj(tbl, "clientValue", s->clientValue);
0900
    WtTableSetStrToObj(tbl, "clientId", s->clientId ?
0901
      s->clientId : WtNewString(NULL));
0902
    WtTableSetStrToLong(tbl, "clientTimeStamp",
0903
      (long)s->clientTimeStamp);
0904
    Tcl_SetObjResult(interp, tbl);
0905
    ret = TCL_OK;
0906
  } else {
0907
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0908
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0909
  }
0910
0911
  return ret;
0912
}
0913
0914
/* delete command */
0915
0916
int WtProcSessionDeleteCmd(ClientData clientData, Tcl_Interp *interp,
0917
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0918
{
0919
  int ret = TCL_ERROR;
0920
0921
  if (objc == 2 || objc == 3) {
0922
    if (WtDeleteProcSession(sh, (objc == 3 ? objv[2] : NULL),
0923
        interp)) {
0924
      ret = TCL_OK;
0925
    }
0926
  } else {
0927
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0928
      WtToString(objv[0]), " ", WtToString(objv[1]), " ?id?", NULL);
0929
  }
0930
0931
  return ret;
0932
}
0933
0934
/* sweep command */
0935
0936
int WtProcSessionSweepCmd(ClientData clientData, Tcl_Interp *interp,
0937
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0938
{
0939
  int ret = TCL_ERROR;
0940
0941
  if (objc == 2) {
0942
    if (WtSweepProcSessions(sh, interp)) {
0943
      ret = TCL_OK;
0944
    }
0945
  } else {
0946
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0947
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0948
  }
0949
0950
  return ret;
0951
}
0952
0953
/* unload command */
0954
0955
int WtProcSessionUnloadCmd(ClientData clientData, Tcl_Interp *interp,
0956
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0957
{
0958
  int ret = TCL_ERROR;
0959
0960
  if (objc == 2) {
0961
    if (!sh->psTable || WtCloseProcSession(sh, interp)) {
0962
      ret = TCL_OK;
0963
    }
0964
  } else {
0965
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0966
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0967
  }
0968
0969
  return ret;
0970
}
0971
0972
/* load command */
0973
0974
int WtProcSessionLoadModuleCmd(ClientData clientData, Tcl_Interp *interp,
0975
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0976
{
0977
  int ret = TCL_ERROR;
0978
0979
  if (objc != 2) {
0980
    Tcl_AppendResult(interp, wtBadUsagePrefix,
0981
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
0982
  } else {
0983
    /* Do nothing */
0984
    ret = TCL_OK;
0985
  }
0986
0987
  return ret;
0988
}
0989
0990
/* unloadModule command */
0991
0992
int WtProcSessionUnloadModuleCmd(ClientData clientData, Tcl_Interp *interp,
0993
    WtProcSession *sh, int objc, Tcl_Obj *const objv[])
0994
{
0995
  WtContext *w;
0996
  int ret = TCL_ERROR;
0997
0998
  if (objc == 2) {
0999
    if (!sh->psTable || WtCloseProcSession(sh, interp)) {
1000
      ret = TCL_OK;
1001
    }
1002
    w = WtGetAssocContext(interp);
1003
    Tcl_DecrRefCount(w->web->session.procSession);
1004
    w->web->session.procSession = NULL;
1005
  } else {
1006
    Tcl_AppendResult(interp, wtBadUsagePrefix,
1007
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
1008
  }
1009
1010
  return ret;
1011
}
1012
1013
/* finalizeRequest command */
1014
1015
int WtProcSessionFinalizeCmd(ClientData clientData, Tcl_Interp *interp,
1016
                           WtProcSession *sh, int objc, Tcl_Obj *const objv[])
1017
{
1018
  int ret = TCL_ERROR;
1019
1020
  if (objc == 2) {
1021
    if (WtProcSessionFinalizeRequest(sh, interp)) {
1022
      ret = TCL_OK;
1023
    }
1024
  } else {
1025
    Tcl_AppendResult(interp, wtBadUsagePrefix,
1026
      WtToString(objv[0]), " ", WtToString(objv[1]), NULL);
1027
  }
1028
1029
  return ret;
1030
}
1031
1032
/* Initialize the session and retrieve the stroage table */
1033
1034
Tcl_Obj *WtGetPSStorage(WtProcSession *sh, Tcl_Interp *interp)
1035
{
1036
  Tcl_Obj *mt = NULL;
1037
  if (WtInitProcSession(sh, interp)) {
1038
    mt = WtPSTableRep(sh->psTable)->sharedTable;
1039
  }
1040
  return mt;
1041
}
1042
1043
/* Create session commands */
1044
1045
void WtInitProcSessionCommands(Tcl_Interp *interp)
1046
{
1047
  Tcl_CreateObjCommand(interp, "::wt::session::procSession::procSessionHandler",
1048
    WtProcSessionCmd, NULL, NULL);
1049
}
1050
1051
/* Process session type */
1052
1053
/* Create */
1054
1055
Tcl_Obj *WtNewProcSessionObj()
1056
{
1057
  Tcl_Obj *obj;
1058
  WtProcSession *sh = (WtProcSession *)ckalloc(sizeof(WtProcSession));
1059
1060
  sh->initDone = 0;
1061
  sh->id = NULL;
1062
  sh->psTable = NULL;
1063
  sh->isNew = 0;
1064
  sh->isModified = 0;
1065
1066
  obj = Tcl_NewObj();
1067
  obj->internalRep.twoPtrValue.ptr1 = sh;
1068
  obj->internalRep.twoPtrValue.ptr2 = NULL;
1069
  obj->typePtr = &WtProcSessionType;
1070
  Tcl_InvalidateStringRep(obj);
1071
  return obj;
1072
}
1073
1074
/* Copy */
1075
1076
static void WtProcSessionDup(Tcl_Obj *src, Tcl_Obj *dst)
1077
{
1078
  WtProcSession *srcRep = WtProcSessionRep(src);
1079
  WtProcSession *dstRep = (WtProcSession *)ckalloc(
1080
    sizeof(WtProcSession));
1081
1082
  dstRep->initDone = srcRep->initDone;
1083
1084
  if (srcRep->id) {
1085
    dstRep->id = srcRep->id;
1086
    Tcl_IncrRefCount(dstRep->id);
1087
  } else {
1088
    dstRep->id = NULL;
1089
  }
1090
1091
  if (srcRep->psTable) {
1092
    dstRep->psTable = srcRep->psTable;
1093
    Tcl_IncrRefCount(dstRep->psTable);
1094
  } else {
1095
    dstRep->psTable = NULL;
1096
  }
1097
1098
  dstRep->isNew = srcRep->isNew;
1099
  dstRep->isModified = srcRep->isModified;
1100
  dst->internalRep.twoPtrValue.ptr1 = dstRep;
1101
  dst->internalRep.twoPtrValue.ptr2 = NULL;
1102
  dst->typePtr = &WtProcSessionType;
1103
  Tcl_InvalidateStringRep(dst);
1104
}
1105
1106
/* Update the string rep */
1107
1108
static void WtProcSessionUpdateString(Tcl_Obj *obj)
1109
{
1110
  WtUpdateProtectedObjString(obj);
1111
}
1112
1113
/* Convert */
1114
1115
static int WtProcSessionSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj)
1116
{
1117
  return WtSetProtectedObjFromAny(interp, obj, &WtProcSessionType);
1118
}
1119
1120
/* Free */
1121
1122
static void WtProcSessionFree(Tcl_Obj *obj)
1123
{
1124
  WtProcSession *sh = WtProcSessionRep(obj);
1125
  if (sh->id) {
1126
    Tcl_DecrRefCount(sh->id);
1127
    sh->id = NULL;
1128
  }
1129
  if (sh->psTable) {
1130
    Tcl_DecrRefCount(sh->psTable);
1131
    sh->psTable = NULL;
1132
  }
1133
  ckfree((char *)(sh));
1134
}
1135
1136
WtProcSession *WtProcSessionRep(Tcl_Obj *obj)
1137
{
1138
  return (WtProcSession *)obj->internalRep.twoPtrValue.ptr1;
1139
}
1140
1141
/* Process session type */
1142
1143
struct Tcl_ObjType WtProcSessionType =
1144
{
1145
  "procSession",
1146
  WtProcSessionFree,
1147
  WtProcSessionDup,
1148
  WtProcSessionUpdateString,
1149
  WtProcSessionSetFromAny
1150
};
1151
1152
/* Process session table type. This is the storage
1153
   object associated with an in-process session. */
1154
1155
/* Create */
1156
1157
Tcl_Obj *WtNewPSTableObj()
1158
{
1159
  Tcl_Obj *obj;
1160
  WtPSTable *st = (WtPSTable *)ckalloc(sizeof(WtPSTable));
1161
1162
  st->sharedTable = WtNewMtTableObj();
1163
  st->accessTime = -1;
1164
1165
  obj = Tcl_NewObj();
1166
  obj->internalRep.twoPtrValue.ptr1 = st;
1167
  obj->internalRep.twoPtrValue.ptr2 = NULL;
1168
  obj->typePtr = &WtPSTableType;
1169
  Tcl_InvalidateStringRep(obj);
1170
  return obj;
1171
}
1172
1173
/* Copy */
1174
1175
static void WtPSTableDup(Tcl_Obj *src, Tcl_Obj *dst)
1176
{
1177
  WtPSTable *srcRep = WtPSTableRep(src);
1178
  WtPSTable *dstRep = (WtPSTable *)ckalloc(
1179
    sizeof(WtPSTable));
1180
1181
  if (srcRep->sharedTable) {
1182
    dstRep->sharedTable = Tcl_DuplicateObj(srcRep->sharedTable);
1183
    Tcl_IncrRefCount(srcRep->sharedTable);
1184
  } else {
1185
    srcRep->sharedTable = NULL;
1186
  }
1187
1188
  dstRep->accessTime = srcRep->accessTime;
1189
  dst->internalRep.twoPtrValue.ptr1 = dstRep;
1190
  dst->internalRep.twoPtrValue.ptr2 = NULL;
1191
  dst->typePtr = &WtPSTableType;
1192
  Tcl_InvalidateStringRep(dst);
1193
}
1194
1195
/* Update the string rep */
1196
1197
static void WtPSTableUpdateString(Tcl_Obj *obj)
1198
{
1199
  WtUpdateProtectedObjString(obj);
1200
}
1201
1202
/* Convert */
1203
1204
static int WtPSTableSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj)
1205
{
1206
  return WtSetProtectedObjFromAny(interp, obj, &WtPSTableType);
1207
}
1208
1209
/* Free */
1210
1211
static void WtPSTableFree(Tcl_Obj *obj)
1212
{
1213
  WtPSTable *st = WtPSTableRep(obj);
1214
  if (st->sharedTable) {
1215
    Tcl_DecrRefCount(st->sharedTable);
1216
  }
1217
  ckfree((char *)(st));
1218
}
1219
1220
WtPSTable *WtPSTableRep(Tcl_Obj *obj)
1221
{
1222
  return (WtPSTable *)obj->internalRep.twoPtrValue.ptr1;
1223
}
1224
1225
/* Process session type */
1226
1227
struct Tcl_ObjType WtPSTableType =
1228
{
1229
  "procSessionTable",
1230
  WtPSTableFree,
1231
  WtPSTableDup,
1232
  WtPSTableUpdateString,
1233
  WtPSTableSetFromAny
1234
};