/[webpac]/branches/humanistika/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

Annotation of /branches/humanistika/openisis/lstb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 237 - (hide annotations)
Mon Mar 8 17:43:12 2004 UTC (19 years, 11 months ago) by dpavlin
Original Path: openisis/current/lstb.c
File MIME type: text/plain
File size: 21647 byte(s)
initial import of openisis 0.9.0 vendor drop

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: 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