1 |
/* |
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 |
} |