1 |
dpavlin |
237 |
/* |
2 |
|
|
openisis - an open implementation of the CDS/ISIS database |
3 |
|
|
Version 0.8.x (patchlevel see file Version) |
4 |
|
|
Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org |
5 |
|
|
|
6 |
|
|
This library is free software; you can redistribute it and/or |
7 |
|
|
modify it under the terms of the GNU Lesser General Public |
8 |
|
|
License as published by the Free Software Foundation; either |
9 |
|
|
version 2.1 of the License, or (at your option) any later version. |
10 |
|
|
|
11 |
|
|
This library is distributed in the hope that it will be useful, |
12 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
|
|
Lesser General Public License for more details. |
15 |
|
|
|
16 |
|
|
You should have received a copy of the GNU Lesser General Public |
17 |
|
|
License along with this library; if not, write to the Free Software |
18 |
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
|
|
|
20 |
|
|
see README for more information |
21 |
|
|
EOH */ |
22 |
|
|
|
23 |
|
|
/* |
24 |
|
|
$Id: oits.c,v 1.13 2003/06/15 15:57:44 mawag Exp $ |
25 |
|
|
OpenIsis Tcl server |
26 |
|
|
*/ |
27 |
|
|
|
28 |
|
|
|
29 |
|
|
#include "lsv.h" |
30 |
|
|
#include "ldsp.h" |
31 |
|
|
#include "openisistcl.h" |
32 |
|
|
|
33 |
|
|
/* |
34 |
|
|
include this after the Tcl stuff for the benefit of those |
35 |
|
|
who use the 150% braindead gcc 2.96 |
36 |
|
|
which barfs on |
37 |
|
|
declaration of `index' shadows global declaration |
38 |
|
|
in generic/tclDecls.h |
39 |
|
|
cause string.h declares |
40 |
|
|
char *index(const char *s, int c) |
41 |
|
|
*/ |
42 |
|
|
#include <string.h> /* mem* */ |
43 |
|
|
|
44 |
|
|
static Tcl_Interp *interp; /* the 1 + only */ |
45 |
|
|
static int oitsid; |
46 |
|
|
static int oitrid[3]; |
47 |
|
|
|
48 |
|
|
|
49 |
|
|
/* the db srv application */ |
50 |
|
|
static int oitdbs (Con *con, int task) { |
51 |
|
|
int rt; |
52 |
|
|
switch ( task ) { |
53 |
|
|
case LSV_APPGOT: |
54 |
|
|
rt = rInt (con->req, OPENISIS_RQS_TYPE, 0, 0); |
55 |
|
|
/* interp evaluation in main thread: */ |
56 |
|
|
con->grp = OPENISIS_RQST_EVAL != rt; |
57 |
|
|
default: |
58 |
|
|
return 0; |
59 |
|
|
case LSV_APPRUN: |
60 |
|
|
break; |
61 |
|
|
} |
62 |
|
|
sMsg( LOG_INFO, "dbs %d: %d fields from %s", |
63 |
|
|
svCur()->id, con->req->len, con->nam); |
64 |
|
|
rt = ldspProcess (con->req, &(con->ses->res), 0, 0); |
65 |
|
|
sMsg( LOG_INFO, "dbs %d: %d fields to %s (%d)", |
66 |
|
|
svCur()->id, con->ses->res->len, con->nam, rt); |
67 |
|
|
return rt; |
68 |
|
|
} |
69 |
|
|
|
70 |
|
|
/* the echo application */ |
71 |
|
|
static int oits ( Con *c, int task ) |
72 |
|
|
{ |
73 |
|
|
Field *f; |
74 |
|
|
int i; |
75 |
|
|
|
76 |
|
|
switch ( task ) { |
77 |
|
|
case LSV_APPINI: /* init thread */ |
78 |
|
|
case LSV_APPFIN: /* fini thread */ |
79 |
|
|
case LSV_APPARG: /* new request param arrived */ |
80 |
|
|
default: |
81 |
|
|
return 0; |
82 |
|
|
case LSV_APPGOT: /* decide wether request may go to background thread */ |
83 |
|
|
c->grp = 1; /* non Tcl */ |
84 |
|
|
for ( i=c->req->len, f = c->req->field; i--; f++ ) |
85 |
|
|
/* by convention, request with fields >99 are handled by Tcl */ |
86 |
|
|
if ( 99 < f->tag ) { |
87 |
|
|
c->grp = 0; |
88 |
|
|
break; |
89 |
|
|
} |
90 |
|
|
return 0; |
91 |
|
|
case LSV_APPRUN: |
92 |
|
|
break; /* main code below */ |
93 |
|
|
} |
94 |
|
|
/* run it */ |
95 |
|
|
sMsg( LOG_INFO, "echo %d: %d fields to %s", |
96 |
|
|
svCur()->id, c->req->len, c->nam ); |
97 |
|
|
/** |
98 |
|
|
we have records: |
99 |
|
|
req -- the request, allocated by the srv->ses and readonly here |
100 |
|
|
ses -- session props, allocated and managed by ses, read/write |
101 |
|
|
res -- the responses, allocated and managed by ses, read/write |
102 |
|
|
|
103 |
|
|
(the identified) ses may be a different session on each call, however, |
104 |
|
|
calls are strictly serialized (all in main thread) |
105 |
|
|
|
106 |
|
|
alternatively, we may use the one main session bound to the |
107 |
|
|
main thread as allocator and use the identified session only |
108 |
|
|
to keep the session props -- given they are never modified |
109 |
|
|
in non-main-thread calls |
110 |
|
|
*/ |
111 |
|
|
switch ( c->grp ) { |
112 |
|
|
case 0: { /* main thread Tcl request */ |
113 |
|
|
Rec *rec[3]; |
114 |
|
|
rec[0] = c->req; |
115 |
|
|
rec[1] = c->ses->res; |
116 |
|
|
rec[2] = c->ses->prop; |
117 |
|
|
if ( openIsisTclEval( oitsid, 3, oitrid, rec, "oitscb" ) ) { |
118 |
|
|
const char *errorInfo |
119 |
|
|
= Tcl_GetVar( interp, "errorInfo", TCL_GLOBAL_ONLY ); |
120 |
|
|
sMsg( LOG_ERROR, "error in callback\n%s", |
121 |
|
|
errorInfo ? errorInfo : "-" ); |
122 |
|
|
} |
123 |
|
|
c->req = rec[0]; |
124 |
|
|
c->ses->res = rec[1]; |
125 |
|
|
c->ses->prop = rec[2]; |
126 |
|
|
/* don't break; */ |
127 |
|
|
} /* case 0 */ |
128 |
|
|
default: /* cp session to response */ |
129 |
|
|
if ( c->ses->prop ) |
130 |
|
|
for ( i=c->ses->prop->len, f = c->ses->prop->field; i--; f++ ) { |
131 |
|
|
RADDF( c->ses->res, f, !0 ); |
132 |
|
|
} |
133 |
|
|
break; |
134 |
|
|
} |
135 |
|
|
return 0; |
136 |
|
|
} /* oits */ |
137 |
|
|
|
138 |
|
|
|
139 |
|
|
#ifdef ORATCL |
140 |
|
|
extern int Oratcl_Init ( Tcl_Interp *ip ); |
141 |
|
|
#endif |
142 |
|
|
#ifdef PGTCL |
143 |
|
|
extern int Pgtcl_Init ( Tcl_Interp *ip ); |
144 |
|
|
#endif |
145 |
|
|
|
146 |
|
|
|
147 |
|
|
int main ( int argc, const char **argv ) |
148 |
|
|
{ |
149 |
|
|
char *file; |
150 |
|
|
int ret, db; |
151 |
|
|
Srv echo; |
152 |
|
|
|
153 |
|
|
cOpen(0); |
154 |
|
|
|
155 |
|
|
Tcl_FindExecutable (argv[0]); |
156 |
|
|
interp = Tcl_CreateInterp(); |
157 |
|
|
ret = Tcl_Init( interp ); |
158 |
|
|
sMsg( LOG_VERBOSE, "appinit %d", ret ); |
159 |
|
|
|
160 |
|
|
db = 0; |
161 |
|
|
if (1 < argc && 0 == strcmp ("-db", argv[1])) { |
162 |
|
|
db = 1; |
163 |
|
|
ret = openIsisTclInit (interp); |
164 |
|
|
sMsg( LOG_VERBOSE, "openisisinit %d", ret); |
165 |
|
|
--argc; |
166 |
|
|
++argv; |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
#ifdef ORATCL |
170 |
|
|
ret = Oratcl_Init( interp ); |
171 |
|
|
sMsg( LOG_VERBOSE, "orainit %d", ret ); |
172 |
|
|
#endif |
173 |
|
|
#ifdef PGTCL |
174 |
|
|
ret = Pgtcl_Init( interp ); |
175 |
|
|
sMsg( LOG_VERBOSE, "pginit %d", ret ); |
176 |
|
|
#endif |
177 |
|
|
oitsid = openIsisTclNewSession( interp ); |
178 |
|
|
sMsg( LOG_VERBOSE, "oitsid %d", oitsid ); |
179 |
|
|
oitrid[0] = openIsisTclCreateRecCmd( oitsid, "request", 0, 0 ); |
180 |
|
|
sMsg( LOG_VERBOSE, "request %d", oitrid[0] ); |
181 |
|
|
oitrid[1] = openIsisTclCreateRecCmd( oitsid, "response", 0, 0 ); |
182 |
|
|
sMsg( LOG_VERBOSE, "response %d", oitrid[1] ); |
183 |
|
|
oitrid[2] = openIsisTclCreateRecCmd( oitsid, "session", 0, 0 ); |
184 |
|
|
sMsg( LOG_VERBOSE, "session %d", oitrid[2] ); |
185 |
|
|
file = 2<argc ? (char*)argv[2] : "oitsrc"; |
186 |
|
|
ret = Tcl_EvalFile( interp, file ); |
187 |
|
|
sMsg( LOG_VERBOSE, "file '%s' %d", file, ret ); |
188 |
|
|
if ( TCL_OK != ret ) { |
189 |
|
|
const char *errorInfo = Tcl_GetVar( interp, "errorInfo", TCL_GLOBAL_ONLY ); |
190 |
|
|
sMsg( LOG_ERROR, "error sourcing file '%s' code %d errorInfo\n%s", |
191 |
|
|
file, ret, errorInfo ? errorInfo : "-" ); |
192 |
|
|
return ret; |
193 |
|
|
} |
194 |
|
|
|
195 |
|
|
memset( &echo, 0, sizeof(echo) ); |
196 |
|
|
echo.prt = svPlain; |
197 |
|
|
echo.app = db ? oitdbs : oits; |
198 |
|
|
return svRun( &echo, 1<argc ? argv[1] : 0 ); |
199 |
|
|
} |