/[webpac]/trunk/openisis/lstb.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/openisis/lstb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 239 - (show annotations)
Mon Mar 8 17:49:13 2004 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 21647 byte(s)
including openisis 0.9.0 into webpac tree

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: lstb.c,v 1.41 2003/06/15 15:57:43 mawag Exp $
25 implementation of client side session and communication functions.
26 */
27
28 #include <errno.h>
29 #include <limits.h> /* PATH_MAX */
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 #include "openisis.h"
35 #include "loi.h"
36 #include "lcli.h"
37 #include "ldb.h"
38 #include "ldsp.h"
39 #include "lfdt.h"
40 #include "luti.h"
41
42 #ifdef WIN32
43 #define snprintf _snprintf
44 #define vsnprintf _vsnprintf
45 #endif
46
47 #define LSTB_STHOSTLEN 32
48
49 #define LSTB_MAXDBS 255 /* according to OPENISIS_DBIDMSK */
50 #define LSTB_MAXSTUBS 255 /* according to OPENISIS_SCIDMSK */
51
52 #define LSTB_INCRDB 8
53 #define LSTB_INCRSTUB 8
54
55 /* ************************************************************
56 * meta
57 */
58
59 /* stub id 0 has idx -1 */
60 /* stub id 0x0100 has idx 0 */
61
62 #define SC_X2I(s) ( ( (1 + (s)) << 8 ) & OPENISIS_SCIDMSK )
63
64 #define SC_I2X(s) ( ( ((s) & OPENISIS_SCIDMSK) >> 8 ) - 1 )
65
66 #define DB_X2I(d,s) ( ((s) & OPENISIS_SCIDMSK) | ((d) & OPENISIS_DBIDMSK) )
67
68 #define DB_I2X(d) ( (d) & OPENISIS_DBIDMSK )
69
70 #define DB_IDX_OK(st,idx) \
71 (0 <= (idx) && (st)->head.ndbs > (idx) && * (st)->head.dbs[idx]->name)
72
73 /* ************************************************************
74 * client view of db
75 */
76
77 typedef struct {
78 Db head;
79 } CDb;
80
81 static void cdbCtor (CDb *that,
82 const char *name, int dbid, int tms, Fdt *fdt, Rec *cfg
83 ) {
84 strncpy (that->head.name, name, DBNLEN - 1) [DBNLEN - 1] = 0;
85 that->head.dbid = dbid;
86 that->head.tms = tms;
87 that->head.fdt = fdt;
88 that->head.cfg = cfg;
89 }
90
91 static void cdbDtor (CDb *that) {
92 if (that->head.fdt) {
93 fFree (that->head.fdt);
94 }
95 if (that->head.cfg) {
96 mFree (that->head.cfg);
97 }
98 memset (that, 0, sizeof (CDb));
99 }
100
101 /* ************************************************************
102 * client session
103 */
104
105 typedef struct OpenIsisStb {
106 Schema head;
107 char host[LSTB_STHOSTLEN];
108 int port;
109 int srq; /* rqs serial no */
110 Rec *rqs; /* last request */
111 Rec *rsp; /* last response */
112 Db *rdb; /* db of embedded rsp recs */
113 CDb *dbase; /* db array of non-local schema */
114 LutiLT hsh;
115 CliChnl chn;
116 OpenIsisStbRqsProc *rqsp;
117 OpenIsisStbDelProc *delp;
118 void *cld; /* client_data of rqsp */
119 /*MMM deprecated*/
120 OpenIsisRspCb *actcb;
121 void *actcld;
122 OpenIsisStubCbData cbdta;
123 } OpenIsisStb;
124
125 Stub stub0 = 0;
126
127 static Stub RmtStubs = 0;
128 static int NumStubs = 0;
129
130 static LutiLT StubLT = 0;
131
132 #define STBSIZE (sizeof(Stb))
133
134 static int stbLocalRqs (Stub that, Rec *rqs);
135 static int stbSyncRqs (Stub that, Rec *rqs);
136
137 static void stbClear (Stub that) {
138 memset (that, 0, STBSIZE);
139 that->chn.sd = -1;
140 }
141
142 static int stbCtor (Stub that,
143 const char *name, int scid, Rec *cfg,
144 OpenIsisStbRqsProc *rqsp, OpenIsisStbDelProc *delp, void *cld,
145 OpenIsisStubCbData *cbd
146 ) {
147 strncpy (that->head.name, name, SCNLEN - 1) [SCNLEN - 1] = 0;
148 that->head.scid = scid;
149 if (scid) {
150 if (! rString (cfg, OPENISIS_SC_HOST, 0, that->host, LSTB_STHOSTLEN)) {
151 return 0;
152 }
153 that->port = rInt (cfg, OPENISIS_SC_PORT, 0, 0);
154 if (0 >= that->port) {
155 return 0;
156 }
157 if (rqsp) {
158 that->rqsp = rqsp;
159 }
160 else {
161 that->rqsp = &stbSyncRqs;
162 }
163 }
164 else {
165 that->rqsp = &stbLocalRqs;
166 }
167 that->head.cfg =
168 rSet (cfg, RCHG | RDIS, OPENISIS_SC_NAME, that->head.name, 0);
169 that->delp = delp;
170 that->cld = cld;
171 that->hsh = luti_ltnew ();
172 if (cbd) {
173 memcpy (&that->cbdta, cbd, sizeof (OpenIsisStubCbData));
174 }
175 luti_ltadd (StubLT, that->head.name, scid);
176 return !0;
177 }
178
179 /* return idx or -err */
180 static int cdbNewIdx (Stub that) {
181 int ndb = that->head.ndbs;
182 int rt, j;
183 for (j = 0; ndb > j; ++j) {
184 if (! * that->dbase[j].head.name) {
185 return j;
186 }
187 }
188 rt = luti_ptrincr (&that->dbase, &ndb,
189 LSTB_INCRDB, sizeof (CDb), LSTB_MAXDBS);
190 if (0 > rt) {
191 return sMsg (ERR_NOMEM, "%s: cdbNewIdx: out of memory",
192 that->head.name);
193 }
194 rt = luti_ptrincr (&that->head.dbs, &that->head.ndbs,
195 LSTB_INCRDB, sizeof (CDb*), LSTB_MAXDBS);
196 if (0 > rt) {
197 return sMsg (ERR_NOMEM, "%s: cdbNewIdx: out of memory",
198 that->head.name);
199 }
200 for (j = that->head.ndbs; 0 <= --j; ) {
201 that->head.dbs[j] = (Db*) (that->dbase + j);
202 }
203 return rt;
204 }
205
206 /* return bool newly allocated or -err */
207 static int cdbNewIdx0 (Stub that, int dbid) {
208 int rt;
209 if (dbid < that->head.ndbs) {
210 if (that->head.dbs[dbid]) {
211 return 0;
212 }
213 return 1;
214 }
215 rt = luti_ptrincr (&that->head.dbs, &that->head.ndbs,
216 1 + dbid - that->head.ndbs, sizeof (CDb*), -1);
217 if (0 > rt) {
218 return sMsg (ERR_NOMEM, "%s: cdbNewIdx0(%d): out of memory",
219 that->head.name, dbid);
220 }
221 return 1;
222 }
223
224 static int stbNewIdx () {
225 int j;
226 for (j = 0; NumStubs > j; ++j) {
227 if (! * RmtStubs[j].head.name) {
228 return j;
229 }
230 }
231 j = luti_ptrincr (&RmtStubs, &NumStubs,
232 LSTB_INCRSTUB, STBSIZE, LSTB_MAXSTUBS);
233 /* stbClear (RmtStubs + j) done in nOpen */
234 return j;
235 }
236
237 static Stub stbById (int sid) {
238 int idx;
239 if (0 > sid || ! stub0) {
240 return 0;
241 }
242 if (0 == sid) {
243 return stub0;
244 }
245 idx = SC_I2X (sid);
246 if (0 > idx) {
247 log_msg (LOG_ERROR, "stbById: illegal id %x", sid);
248 return 0;
249 }
250 if (NumStubs <= idx) {
251 return 0;
252 }
253 if (! * RmtStubs[idx].head.name) {
254 return 0;
255 }
256 return RmtStubs + idx;
257 }
258
259 static void stbDtor (Stub that) {
260 luti_ltrmv (StubLT, that->head.name);
261 if (that->cbdta.delcb) {
262 if (that->actcld) {
263 (*that->cbdta.delcb) (
264 that->cbdta.delcld, that, that->actcld);
265 }
266 if (that->cbdta.dfltcld) {
267 (*that->cbdta.delcb) (
268 that->cbdta.delcld, that, that->cbdta.dfltcld);
269 }
270 (*that->cbdta.delcb) (that->cbdta.delcld, that, 0);
271 }
272 if (that->dbase) {
273 int j;
274 for (j = that->head.ndbs; 0 <= --j; ) {
275 if (* that->dbase[j].head.name) {
276 cdbDtor (that->dbase + j);
277 }
278 }
279 mFree (that->dbase);
280 }
281 if (that->head.dbs) {
282 mFree (that->head.dbs);
283 }
284 if (that->head.cfg) {
285 mFree (that->head.cfg);
286 }
287 luti_ltdel (that->hsh);
288 nClean (that);
289 stbClear (that);
290 }
291
292 static int stbDbidFromName (Stub that, const char *dbn) {
293 int id;
294 if (! dbn) {
295 return -1;
296 }
297 id = luti_ltget (that->hsh, dbn);
298 return id;
299 }
300
301 static int stbDbIdxFromName (Stub that, const char *dbn) {
302 int idx = stbDbidFromName (that, dbn);
303 if (0 > idx) {
304 return -1;
305 }
306 idx = DB_I2X (idx);
307 if (! DB_IDX_OK (that, idx)) {
308 return -1;
309 }
310 return idx;
311 }
312
313 static int stbOpenDb (Stub that) {
314 char dbn[DBNLEN];
315 Fdt *fdt;
316 Rec *cfg;
317 int idx, dbid, tms;
318 int newdb = 0;
319
320 if (! rString (that->rsp, OPENISIS_COM_DBN, 0, dbn, DBNLEN)) {
321 return sMsg (ERR_IDIOT, "%s: stbOpenDb: missing db name in rsp",
322 that->head.name);
323 }
324 idx = stbDbIdxFromName (that, dbn);
325
326 if (0 > idx) {
327 idx = cdbNewIdx (that);
328 if (0 > idx) {
329 return idx;
330 }
331 newdb = !0;
332 }
333 else {
334 cdbDtor (that->dbase + idx);
335 }
336
337 fdt = fRec2Fdt (that->rsp);
338 cfg = luti_unwrap (that->rsp, 0, OPENISIS_COM_CFG, -1);
339 tms = rInt (that->rsp, OPENISIS_COM_TMS, 0, 0);
340 dbid = DB_X2I (idx, that->head.scid);
341
342 cdbCtor (that->dbase + idx, dbn, dbid, tms, fdt, cfg);
343
344 if (newdb) {
345 luti_ltadd (that->hsh, dbn, dbid);
346 }
347 return 0;
348 }
349
350 static int stbOpenDb0 (Stub that) {
351 Db *dbh;
352 int newdb = 0;
353 int dbid = rInt (that->rsp, OPENISIS_RSP_DBID, -1, 0);
354 if (0 > dbid) {
355 return sMsg (ERR_IDIOT, "stbOpenDb0: missing dbid in rsp");
356 }
357
358 newdb = cdbNewIdx0 (that, dbid);
359 if (0 > newdb) {
360 return newdb;
361 }
362
363 dbh = ldb_getdb (dbid);
364 if (! dbh) {
365 return sMsg (ERR_TRASH, "stbOpenDb0: no such db %d", dbid);
366 }
367 log_msg (LOG_INFO, "stbOpenDb0 %d %s", dbid, dbh->name);
368
369 that->head.dbs[dbid] = dbh;
370 if (newdb) {
371 luti_ltadd (that->hsh, dbh->name, dbid);
372 }
373 return 0;
374 }
375
376 static int stbCloseDb (Stub that) {
377 char dbn[DBNLEN];
378 CDb *db;
379 int dbid;
380 if (! rString (that->rsp, OPENISIS_COM_DBN, 0, dbn, sizeof (dbn))) {
381 return sMsg (ERR_IDIOT, "%s: stbCloseDb: missing db name in rsp",
382 that->head.name);
383 }
384 dbid = stbDbIdxFromName (that, dbn);
385 if (0 > dbid) {
386 return sMsg (ERR_TRASH, "%s: stbCloseDb: illegal db name <%s> in rsp",
387 that->head.name, dbn);
388 }
389 db = that->dbase + dbid;
390 luti_ltrmv (that->hsh, db->head.name);
391 cdbDtor (db);
392 return 0;
393 }
394
395 static int stbCloseDb0 (Stub that) {
396 char dbn[DBNLEN];
397 int dbid = rInt (that->rsp, OPENISIS_RSP_DBID, -1, 0);
398 if (0 > dbid) {
399 return sMsg (ERR_IDIOT, "stbCloseDb0: missing dbid in rsp");
400 }
401 if (that->head.ndbs <= dbid) {
402 return sMsg (ERR_TRASH, "stbCloseDb0: illegal dbid %d(%d) in rsp",
403 dbid, that->head.ndbs);
404 }
405 if (! rString (that->rsp, OPENISIS_COM_DBN, 0, dbn, DBNLEN)) {
406 return sMsg (ERR_IDIOT, "stbCloseDb0: missing db name in rsp\n");
407 }
408 log_msg (LOG_INFO, "stbCloseDb0 %d %s", dbid, dbn);
409 luti_ltrmv (that->hsh, dbn);
410 that->head.dbs[dbid] = 0;
411 return 0;
412 }
413
414 /* (local) response callback
415 */
416 static int stbRspCb (Rec **rsp, void *cld) {
417 Stub that;
418 Rec *rsp2;
419 int sid, ser, err, err2, err3;
420
421 (void)cld;
422 sid = rInt (*rsp, OPENISIS_COM_SID, -1, 0);
423 ser = rInt (*rsp, OPENISIS_COM_SER, -1, 0);
424 err = rInt (*rsp, OPENISIS_RSP_ERR, -1, 0);
425
426 that = stbById (sid);
427 if (! that) {
428 return sMsg (ERR_TRASH, "illegal stub id %d in stbRspCb\n", sid);
429 }
430 if (ser != that->srq) {
431 return sMsg (ERR_TRASH, "%s: rqs serial mismatch %d != %d",
432 that->head.name, ser, that->srq);
433 }
434 if (! that->rqs) {
435 return sMsg (ERR_TRASH, "%s/%d: response without request",
436 that->head.name, sid);
437 }
438 if (that->rsp) {
439 sMsg (ERR_TRASH, "%s: multiple responses",
440 that->head.name);
441 mFree (that->rsp);
442 }
443 that->rdb = 0;
444 that->rsp = *rsp;
445 *rsp = 0;
446
447 err2 = err3 = 0;
448
449 if (0 == err) {
450 int rtyp = rInt (that->rqs, OPENISIS_RQS_TYPE, -1, 0);
451 switch (rtyp) {
452
453 case OPENISIS_RQST_LSDB:
454 case OPENISIS_RQST_EVAL:
455 break;
456
457 case OPENISIS_RQST_CLOS:
458 if (sid) {
459 err2 = sMsg (ERR_IDIOT, "%s: db close on remote stub",
460 that->head.name);
461 }
462 else {
463 err2 = stbCloseDb0 (that);
464 }
465 break;
466
467 case OPENISIS_RQST_OPEN:
468 if (sid) {
469 err2 = sMsg (ERR_IDIOT, "%s: db open on remote stub",
470 that->head.name);
471 break;
472 }
473 err2 = stbOpenDb0 (that);
474 goto setdb;
475
476 case OPENISIS_RQST_MNT:
477 if (0 == sid) {
478 err2 = sMsg (ERR_IDIOT, "db mount on local stub");
479 break;
480 }
481 err2 = stbOpenDb (that);
482 goto setdb;
483
484 default:
485 setdb: {
486 char dbn[DBNLEN];
487 int rdid, rx;
488 if (! rString (that->rsp, OPENISIS_COM_DBN, 0, dbn, sizeof(dbn))) {
489 if (sid) {
490 err2 = sMsg (ERR_IDIOT,
491 "%s: stbRspCb: missing db name in rsp",
492 that->head.name);
493 }
494 else {
495 err2 = sMsg (ERR_IDIOT,
496 "stbRspCb: missing db name in rsp");
497 }
498 }
499 else {
500 rdid = stbDbidFromName (that, dbn);
501 if (0 > rdid) {
502 if (sid) {
503 err2 = sMsg (ERR_TRASH,
504 "%s: stbRspCb: illegal db name <%s> in rsp",
505 that->head.name, dbn);
506 }
507 else {
508 err2 = sMsg (ERR_TRASH,
509 "stbRspCb: illegal db name <%s> in rsp", dbn);
510 }
511 }
512 else {
513 /* see nDbById */
514 rx = DB_I2X (rdid);
515 if (! DB_IDX_OK (that, rx)) {
516 if (sid) {
517 err2 = sMsg (ERR_TRASH,
518 "%s: stbRspCb: illegal db id %d %d <%s>",
519 that->head.name, rdid, rx, dbn);
520 }
521 else {
522 err2 = sMsg (ERR_TRASH,
523 "stbRspCb: illegal db id %d %d <%s>",
524 rdid, rx, dbn);
525 }
526 }
527 else {
528 that->rdb = that->head.dbs[rx];
529 }
530 }
531 }
532 }
533 } /* switch */
534 }
535 else { /* err */
536 int tms;
537 tms = rInt (that->rsp, OPENISIS_COM_TMS, 0, 0);
538 if (tms && sid) { /* remounted */
539 err2 = stbCloseDb (that);
540 }
541 }
542
543 rsp2 = rAddI (that->rsp, OPENISIS_RSP_CERR, err2, !0);
544 if (rsp2) {
545 that->rsp = rsp2;
546 }
547
548 if (that->actcb) {
549 err3 = (*that->actcb) (that->actcld,
550 that, that->rsp, that->rdb);
551 if (that->actcld && that->cbdta.delcb) {
552 (*that->cbdta.delcb) (
553 that->cbdta.delcld, that, that->actcld);
554 }
555 that->actcb = 0;
556 that->actcld = 0;
557 }
558 else if (that->cbdta.dfltcb) {
559 err3 = (*that->cbdta.dfltcb) (that->cbdta.dfltcld,
560 that, that->rsp, that->rdb);
561 }
562
563 sMsg (LOG_VERBOSE, "stbRspCb(%s): %d/%d err = %x,%x,%x",
564 that->head.name, sid, ser, err, err2, err3);
565
566 return err3;
567 }
568
569 static int stbLocalRqs (Stub that, Rec *rqs) {
570 (void)that;
571 return ldspProcess (rqs, 0, &stbRspCb, 0);
572 }
573
574 static int stbSyncRqs (Stub that, Rec *rqs) {
575 Rec *rsp;
576 int rt;
577 if (0 > that->chn.sd) {
578 rt = cliConnect (&that->chn, that->host, that->port);
579 if (0 > rt) {
580 return rt;
581 }
582 }
583 rt = cliWrite (&that->chn, rqs);
584 if (0 > rt) {
585 return rt;
586 }
587 rsp = cliRead (&that->chn);
588 if (! rsp) {
589 return sMsg (ERR_IO, "stbSyncRqs: read error %d - %s",
590 that->chn.err, strerror (that->chn.err));
591 }
592 rt = stbRspCb (&rsp, 0);
593 if (rsp) {
594 mFree (rsp);
595 }
596 return rt;
597 }
598
599 /* ************************************************************
600 package functions
601 */
602
603 /* ************************************************************
604 public functions
605 */
606
607 Stub nInit (
608 int argc, const char **argv, OpenIsisStubCbData *dta
609 ) {
610 Rec *cfg = 0;
611
612 if (stub0) {
613 return stub0;
614 }
615
616 StubLT = luti_ltnew ();
617 stub0 = mAlloc (STBSIZE);
618 stbClear (stub0);
619
620 if (0 < argc) {
621 char buf[PATH_MAX];
622 char *logn;
623 int logl;
624
625 cfg = rSet (0, RFDT | RARGV | RIGN | argc, openIsisFdtSyspar, argv);
626
627 logn = rString (cfg, OPENISIS_SLOGF, 0, buf, sizeof(buf));
628 logl = rInt (cfg, OPENISIS_SLOGV, -1, 0);
629 if (logn || 0 <= logl) {
630 cLog (logl, logn);
631 }
632 }
633
634 stbCtor (stub0, "", 0, cfg, 0, 0, 0, dta);
635 return stub0;
636 }
637
638 Stub nOpen (
639 const char *name, int argc, const char *argv[], OpenIsisStubCbData *dta
640 ) {
641 OpenIsisStb buf;
642 Stub that;
643 Rec *cfg = 0;
644 int idx, sid;
645
646 if (! stub0 || ! name || ! *name) {
647 return 0;
648 }
649
650 idx = luti_ltget (StubLT, name);
651 if (0 <= idx) {
652 idx = SC_I2X (idx);
653 if (0 > idx || NumStubs <= idx || ! * RmtStubs[idx].head.name) {
654 log_msg (LOG_ERROR, "nOpen: illegal idx %d(%d) for %s",
655 idx, NumStubs, name);
656 return 0;
657 }
658 return RmtStubs + idx;
659 }
660
661 idx = stbNewIdx ();
662 if (0 > idx) {
663 return 0;
664 }
665 if (0 < argc) {
666 cfg = rSet (0, RFDT | RARGV | RIGN | argc, openIsisFdtScheme, argv);
667 }
668 sid = SC_X2I (idx);
669 stbClear (&buf);
670 if (! stbCtor (&buf, name, sid, cfg, 0, 0, 0, dta)) {
671 if (cfg) {
672 mFree (cfg);
673 }
674 return 0;
675 }
676
677 that = RmtStubs + idx;
678 memcpy (that, &buf, STBSIZE);
679 return that;
680 }
681
682 void nClose (Stub that) {
683 if (that && *that->head.name) {
684 stbDtor (that);
685 }
686 }
687
688 void nDeinit () {
689 if (stub0) {
690 int j;
691 if (RmtStubs) {
692 for (j = NumStubs; 0 <= --j; ) {
693 if (* RmtStubs[j].head.name) {
694 stbDtor (RmtStubs + j);
695 }
696 }
697 mFree (RmtStubs);
698 RmtStubs = 0;
699 NumStubs = 0;
700 }
701 for (j = stub0->head.ndbs; 0 <= --j; ) {
702 if (stub0->head.dbs[j]) {
703 cDClose (stub0->head.dbs[j]->dbid);
704 }
705 }
706 stbDtor (stub0);
707 mFree (stub0);
708 stub0 = 0;
709 luti_ltdel (StubLT);
710 StubLT = 0;
711 }
712 }
713
714 Schema* nSchema (Stub that) {
715 int idx;
716 if (that && ( stub0 == that || ( *that->head.name &&
717 0 <= (idx = SC_I2X (that->head.scid)) && NumStubs > idx
718 ))) {
719 return &that->head;
720 }
721 return 0;
722 }
723
724 void nClean (Stub that) {
725 if (that->rqs) {
726 mFree (that->rqs);
727 that->rqs = 0;
728 }
729 if (that->rsp) {
730 mFree (that->rsp);
731 that->rsp = 0;
732 }
733 that->rdb = 0;
734 }
735
736 int nSend (Stub that,
737 Rec *rqs, OpenIsisRspCb *actcb, void *actcld, int dup
738 ) {
739 char buf[DBNLEN];
740 char sid[16];
741 char ser[16];
742 char tms[16];
743 char *dbl, *dbn;
744 int dbid, rtyp, setn;
745
746 if (!(that && rqs)) {
747 return sMsg (ERR_IDIOT, "nSend: null pointer %x %x",
748 (int)that, (int)rqs);
749 }
750 if (stub0 != that && ! *that->head.name) {
751 return sMsg (ERR_IDIOT, "nSend: invalid stub");
752 }
753 setn = !0;
754 rtyp = rInt (rqs, OPENISIS_RQS_TYPE, -1, 0);
755 switch (rtyp) {
756 case -1:
757 return sMsg (ERR_IDIOT, "nSend(%s): request without type",
758 that->head.name);
759 case OPENISIS_RQST_LSDB:
760 case OPENISIS_RQST_EVAL:
761 setn = 0;
762 break;
763 case OPENISIS_RQST_OPEN:
764 case OPENISIS_RQST_CLOS:
765 if (stub0 != that) {
766 return sMsg (ERR_IDIOT, "nSend(%s): request %d denied",
767 that->head.name, rtyp);
768 }
769 break;
770 case OPENISIS_RQST_MNT:
771 if (stub0 == that) {
772 return sMsg (ERR_IDIOT, "nSend: local mount denied");
773 }
774 rqs = rSet (rqs, RFDT | RDIS | RCHG, openIsisFdtRqs,
775 OPENISIS_COM_TMS, "0", 0);
776 if (! rqs) {
777 return sMsg (ERR_NOMEM, "nSend(%s): out of memory",
778 that->head.name);
779 }
780 break;
781 }
782
783 dbid = -1;
784 dbn = 0;
785 dbl = that->rdb ? that->rdb->name : 0;
786 nClean (that);
787
788 i2a (sid, that->head.scid);
789 if (0 >= ++that->srq) {
790 that->srq = 1;
791 log_msg (LOG_INFO, "stub %s: srq loop over 0", that->head.name);
792 }
793 i2a (ser, that->srq);
794
795 if (setn) {
796 if ((dbn = rString (rqs, OPENISIS_COM_DBN, 0, buf, DBNLEN))) {
797 setn = 0;
798 }
799 else {
800 if (dbl) {
801 dbn = dbl;
802 }
803 else {
804 dbn = rString (that->head.cfg,
805 OPENISIS_SC_DFLTDB, 0, buf, DBNLEN);
806 }
807 }
808 if (! dbn) {
809 return sMsg (ERR_IDIOT, "nSend(%s): request without db name",
810 that->head.name);
811 }
812 if (0 > rInt (rqs, OPENISIS_COM_TMS, -1, 0)) {
813 dbid = stbDbIdxFromName (that, dbn);
814 if (0 <= dbid) {
815 i2a (tms, that->head.dbs[dbid]->tms);
816 }
817 }
818 }
819
820 if (dup) {
821 rqs = rDup (rqs, 0, 0);
822 if (! rqs) {
823 return -1;
824 }
825 }
826
827 rqs = rSet (rqs, RFDT | RDIS | RCHG, openIsisFdtRqs,
828 OPENISIS_COM_SID, sid, OPENISIS_COM_SER, ser,
829 0 <= dbid ? OPENISIS_COM_TMS : 0, tms, 0);
830 if (! rqs) {
831 return sMsg (ERR_NOMEM, "nSend(%s): out of memory",
832 that->head.name);
833 }
834 if (setn) {
835 rqs = rSet (rqs, RFDT | RDIS | RCHG, openIsisFdtRqs,
836 OPENISIS_COM_DBN, dbn, 0);
837 if (! rqs) {
838 return sMsg (ERR_NOMEM, "nSend(%s): out of memory",
839 that->head.name);
840 }
841 }
842
843 that->rqs = rqs;
844
845 if (that->actcld && that->cbdta.delcb) {
846 /* ooups */
847 (*that->cbdta.delcb) (
848 that->cbdta.delcld, that, that->actcld);
849 }
850 if (actcb) {
851 that->actcb = actcb;
852 that->actcld = actcld;
853 }
854 else {
855 that->actcb = 0;
856 that->actcld = 0;
857 }
858
859 return (*that->rqsp) (that, that->rqs);
860 }
861
862 Rec* nRecv (Stub that, Db **db) {
863 if (that && (
864 stub0 == that || *that->head.name
865 )) {
866 if (db) {
867 *db = that->rdb;
868 }
869 return that->rsp;
870 }
871 return 0;
872 }
873
874 Db* nDbByName (Stub that, const char *dbname) {
875 if (that && (
876 stub0 == that || *that->head.name
877 )) {
878 int dbid = stbDbIdxFromName (that, dbname);
879 if (0 <= dbid) {
880 return that->head.dbs[dbid];
881 }
882 }
883 return 0;
884 }
885
886 Db* nDbById (int id) {
887 Stub that = stbById (id & OPENISIS_SCIDMSK);
888 if (! that) {
889 return 0;
890 }
891 id = DB_I2X (id);
892 if (! DB_IDX_OK (that, id)) {
893 return 0;
894 }
895 return that->head.dbs[id];
896 }
897
898 #define FREEPTR(p) if (p) { mFree (p); p = 0; }
899 #define FREEROW if (rowids) { FREEPTR(*rowids) }
900
901 int nResult (
902 Stub that, int **rowids, Rec ***recs, Db **db, int *tot
903 ) {
904 Field *F;
905 Rec **R;
906 int *I;
907 int numt, numr, err, pos, j;
908
909 if (rowids) {
910 *rowids = 0;
911 }
912 if (recs) {
913 *recs = 0;
914 }
915 if (db) {
916 *db = 0;
917 }
918 if (tot) {
919 *tot = 0;
920 }
921 if (! that) {
922 return sMsg (ERR_IDIOT, "nGetResult: null pointer");
923 }
924 if (! that->rsp) {
925 return sMsg (ERR_IDIOT, "nGetResult(%s): no response",
926 that->head.name);
927 }
928 err = rInt (that->rsp, OPENISIS_RSP_ERR, 0, 0);
929 if (err) {
930 return sMsg (ERR_IDIOT, "nGetResult(%s): response error %d",
931 that->head.name, err);
932 }
933 numr = rInt (that->rsp, OPENISIS_RSP_NUMR, -1, 0);
934 numt = rInt (that->rsp, OPENISIS_RSP_NUMT, -1, 0);
935 if (0 > numr || 0 > numt) {
936 return sMsg (ERR_IDIOT, "nGetResult(%s): no record count in response",
937 that->head.name);
938 }
939 if (numr) {
940 if (rowids) {
941 *rowids = (int*) mAlloc (numr * sizeof (int));
942 if (! *rowids) {
943 return sMsg (ERR_NOMEM, "nGetResult(%s): out of memory",
944 that->head.name);
945 }
946 for (I = *rowids, j = pos = 0; numr > j; ++I, ++j) {
947 *I = rInt (that->rsp, OPENISIS_COM_ROW, -1, &pos);
948 if (0 > *I) {
949 FREEROW;
950 return sMsg (ERR_TRASH,
951 "nGetResult(%s): missing rowid %d(%d)",
952 that->head.name, j, numr);
953 }
954 }
955 }
956
957 if (recs) {
958 *recs = (Rec**) mAlloc (numr * sizeof (Rec*));
959 if (! *recs) {
960 FREEROW;
961 return sMsg (ERR_NOMEM, "nGetResult(%s): out of memory",
962 that->head.name);
963 }
964 memset (*recs, 0, numr * sizeof (Rec*));
965 R = *recs;
966 I = rowids ? *rowids : 0;
967 j = pos = 0;
968 F = rGet (that->rsp, OPENISIS_COM_REC, &pos);
969 if (! F) {
970 sMsg (LOG_WARN,
971 "nGetResult(%s): no records in response",
972 that->head.name);
973 FREEPTR (*recs);
974 }
975 else {
976 --pos;
977 while (numr > j) {
978 *R = luti_unwrap (that->rsp, &pos, OPENISIS_COM_REC,
979 that->rdb ? that->rdb->dbid : -1);
980 if (! *R) {
981 FREEROW;
982 luti_free ((void**)*recs, j);
983 *recs = 0;
984 return sMsg (ERR_NOMEM,
985 "nGetResult(%s): out of memory", that->head.name);
986 }
987 if (I) {
988 (*R)->rowid = *I;
989 ++I;
990 }
991 ++R;
992 ++j;
993 }
994 }
995 } /* recs */
996
997 } /* numr */
998
999 if (db) {
1000 *db = that->rdb;
1001 }
1002 if (tot) {
1003 *tot = numt;
1004 }
1005
1006 return numr;
1007 }
1008

  ViewVC Help
Powered by ViewVC 1.1.26