/[webpac]/trunk/openisis/ldsp.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 /trunk/openisis/ldsp.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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: ldsp.c,v 1.32 2003/06/15 15:57:43 mawag Exp $
25     server side request processing.
26     */
27    
28     #include <errno.h>
29     #include <limits.h> /* PATH_MAX */
30     #include <stdarg.h>
31     #include <stdio.h> /* vsnprintf */
32     #include <string.h>
33    
34     #include "openisis.h"
35     #include "loi.h"
36     #include "ldb.h"
37     #include "ldsp.h"
38     #include "lfdt.h"
39     /* #include "lsv.h" */
40     #include "luti.h"
41    
42     #ifdef WIN32
43     #define vsnprintf _vsnprintf
44     #endif
45    
46     #define ISID 0
47     #define ISER 1
48     #define ITMS 2
49     #define SSTS 3
50    
51     #define RSPVAR \
52     Db *dbh = 0; \
53     Rec *rsp = 0; \
54     int sdbid;
55    
56     #define RSPADDR \
57     if (! rspa) { rspa = &rsp; }
58    
59     #define RSPHEAD \
60     *rspa = rAddI (*rspa, OPENISIS_COM_SID, sst[ISID], !0); \
61     *rspa = rAddI (*rspa, OPENISIS_COM_SER, sst[ISER], !0);
62    
63     #define RSPNOERR \
64     *rspa = rAddI (*rspa, OPENISIS_RSP_ERR, 0, !0);
65    
66     #define RSPDB \
67     RADDS (*rspa, OPENISIS_COM_DBN, dbn, !0);
68    
69     #define RSPFREE mFree (rsp);
70    
71     #define GETDB(rname) \
72     sdbid = ldspGetDb (&dbh, sst, dbn); \
73     if (0 > sdbid) { \
74     int rt = _RqsError (sst, ERR_INVAL, rspa, cb, \
75     cld, rname, sst[ITMS] ? \
76     "db %s remounted" : "db %s not open", dbn); \
77     return rt; \
78     }
79    
80     #define RSPFDT \
81     if (dbh->fdt) { \
82     *rspa = openIsisFFdt2Rec (dbh->fdt, *rspa, 0); \
83     } \
84     if (dbh->cfg) { \
85     *rspa = luti_wrap (*rspa, dbh->cfg, OPENISIS_COM_CFG); \
86     }
87    
88     #define DELIVER \
89     if (*rspa) { \
90     int rt = 0; \
91     if (cb) { \
92     rt = (*cb) (rspa, cld); \
93     mFree (*rspa); \
94     } \
95     return rt; \
96     } \
97     return sMsg (ERR_NOMEM, "ldsp: deliver: rsp == 0");
98    
99     #define UTF8REC(rec,inv,rname) \
100     if (openIsisEnc2Utf8 && dbh->cfg) { \
101     char ebuf[128]; \
102     char *enc = rString (dbh->cfg, OPENISIS_DENC, 0, ebuf, sizeof(ebuf)); \
103     if (enc && *enc && strcmp (enc, "utf-8")) { \
104     ldspUtf8Rec (&rec, enc, inv); \
105     } \
106     }
107    
108     /* ************************************************************
109     */
110    
111     static int ldspGetDb (Db **db, int sst[], const char *dbn) {
112     Db *dbh = nDbByName (stub0, dbn);
113     if (! dbh) {
114     sst[ITMS] = 0;
115     return -1;
116     }
117     if (sst[ITMS]) {
118     if (-1 == sst[ITMS] || /* dont want default of rInt call */
119     (dbh->tms && dbh->tms != sst[ITMS])
120     ) {
121     sst[ITMS] = dbh->tms;
122     return -1;
123     }
124     }
125     if (db) {
126     *db = dbh;
127     }
128     return dbh->dbid;
129     }
130    
131     static int ldspUtf8Rec (Rec **rec, const char *enc, int invert) {
132     char buf[4096];
133     const char *dst;
134     Rec *res = 0;
135     Field *F, *E;
136     if (*rec && (*rec)->len) {
137     E = (*rec)->field + (*rec)->len;
138     for (F = (*rec)->field; E > F; ++F) {
139     if (0 == F->len || (1 == F->len && ! *(F->val))) {
140     RADDS (res, F->tag, "", !0);
141     }
142     else {
143     dst = (*openIsisEnc2Utf8) (enc,
144     F->val, F->len, buf, sizeof(buf), invert);
145     if (! dst) {
146     if (res) {
147     mFree (res);
148     }
149     return sMsg (ERR_TRASH,
150     "ldsp: cannot convert %s %s utf8: %.*s",
151     enc, (invert ? "from" : "to"), F->len, F->val);
152     }
153     RADDS (res, F->tag, dst, !0);
154     if (dst != buf && dst != F->val) {
155     (*openIsisEnc2Utf8) (0, dst, 0, 0, 0, 0);
156     }
157     }
158     if (! res) {
159     return sMsg (ERR_NOMEM, "ldsp: convert %s %s utf8: res == 0",
160     enc, (invert ? "from" : "to"));
161     }
162     }
163     res->rowid = (*rec)->rowid;
164     res->dbid = (*rec)->dbid;
165     mFree (*rec);
166     *rec = res;
167     }
168     return 0;
169     }
170    
171     static int _RqsError (
172     int sst[], int err, Rec **rspa, LdspDlvCb *cb,
173     void *cld, const char *rname, const char *fmt, ...
174     ) {
175     Rec *rsp = 0;
176     char msg[OPENISIS_ERRMSGLEN];
177     va_list ap;
178     RSPADDR
179     RSPHEAD
180     sMsg (LOG_VERBOSE, "ldsp: _RqsError %s %x from %d/%d",
181     rname, err, sst[ISID], sst[ISER]);
182     if (sst[ITMS] && -1 != sst[ITMS]) {
183     *rspa = rAddI (*rspa, OPENISIS_COM_TMS, sst[ITMS], !0);
184     }
185     *rspa = rAddI (*rspa, OPENISIS_RSP_ERR, err, !0);
186     if (0 != fmt && 0 != *fmt) {
187     va_start (ap, fmt);
188     vsnprintf (msg, OPENISIS_ERRMSGLEN - 1, fmt, ap);
189     msg[OPENISIS_ERRMSGLEN - 1] = 0;
190     va_end (ap);
191     RADDS (*rspa, OPENISIS_RSP_MSG, msg, !0);
192     sMsg (LOG_WARN, "ldsp: err on rqs %s: %d(%x) - %s",
193     rname, err, err, msg);
194     }
195     else {
196     sMsg (LOG_WARN, "ldsp: err on rqs %s: %d(%x)",
197     rname, err, err);
198     }
199     DELIVER
200     }
201    
202     static int _RqsLsDb (
203     int sst[], Rec **rspa, LdspDlvCb *cb, void *cld
204     ) {
205     Rec *rsp = 0;
206     Schema *sc;
207     char *n;
208     int j;
209     sc = nSchema (stub0);
210     if (! sc) {
211     j = _RqsError (sst, ERR_BADF, rspa, cb, cld,
212     "lsdb", "local schema not initialized");
213     return j;
214     }
215     RSPADDR
216     RSPHEAD
217     RSPNOERR
218     sMsg (LOG_VERBOSE, "ldsp: _RqsLsDb from %d/%d", sst[ISID], sst[ISER]);
219     for (j = 0; sc->ndbs > j; ++j) {
220     if (*(n = sc->dbs[j]->name)) {
221     RADDS (*rspa, OPENISIS_COM_DBN, n, !0);
222     }
223     }
224     DELIVER
225     }
226    
227     static int _RqsEval (
228     int sst[], Rec *cmd, Rec **rspa, LdspDlvCb *cb, void *cld
229     ) {
230     Rec *res = 0;
231     Rec *rsp = 0;
232     int j;
233     if (! openIsisEval) {
234     j = _RqsError (sst, ERR_IDIOT, rspa, cb, cld,
235     "eval", "server has no eval function");
236     mFree (cmd);
237     return j;
238     }
239     j = (*openIsisEval) (cmd, &res);
240     mFree (cmd);
241     RSPADDR
242     RSPHEAD
243     *rspa = rAddI (*rspa, OPENISIS_RSP_ERR, j, !0);
244     if (res) {
245     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMT, 1, !0);
246     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMR, 1, !0);
247     *rspa = rAddI (*rspa, OPENISIS_COM_ROW, 0, !0);
248     *rspa = luti_wrap (*rspa, res, OPENISIS_COM_REC);
249     mFree (res);
250     }
251     else {
252     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMT, 0, !0);
253     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMR, 0, !0);
254     }
255     DELIVER
256     }
257    
258     static int _RqsOpen (
259     int sst[], const char *dbn, Rec *dbpar, Fdt *fdt,
260     Rec **rspa, LdspDlvCb *cb, void *cld
261     ) {
262     #define STRERRNOLEN 128
263     RSPVAR
264     Schema *sc;
265     char msg[STRERRNOLEN];
266     sst[ITMS] = 0;
267     sc = nSchema (stub0);
268     if (! sc) {
269     int rt = _RqsError (sst, ERR_BADF, rspa, cb, cld,
270     "open", "%s: local schema not initialized", dbn);
271     mFree (dbpar);
272     return rt;
273     }
274     sMsg (LOG_VERBOSE, "ldsp: _RqsOpen %s from %d/%d",
275     dbn, sst[ISID], sst[ISER]);
276     errno = 0;
277     dbh = cDOpen (dbn, dbpar, sc->cfg, fdt);
278     if (! dbh) {
279     int rt;
280     strncpy (msg, strerror (errno), STRERRNOLEN - 1)
281     [STRERRNOLEN - 1] = 0;
282     rt = _RqsError (sst, ERR_BADF, rspa, cb, cld,
283     "open", "%s: %s", dbn, msg);
284     mFree (dbpar);
285     return rt;
286     }
287     sdbid = dbh->dbid;
288     dbn = dbh->name;
289     RSPADDR
290     RSPHEAD
291     RSPNOERR
292     RSPDB
293     *rspa = rAddI (*rspa, OPENISIS_RSP_DBID, sdbid, !0);
294     *rspa = rAddI (*rspa, OPENISIS_COM_TMS, dbh->tms, !0);
295     mFree (dbpar);
296     DELIVER
297     }
298    
299     static int _RqsClose (
300     int sst[], const char *dbn, Rec **rspa, LdspDlvCb *cb, void *cld
301     ) {
302     RSPVAR
303     int err;
304     GETDB("close")
305     sMsg (LOG_VERBOSE, "ldsp: _RqsClose %s from %d/%d",
306     dbn, sst[ISID], sst[ISER]);
307     err = cDClose (sdbid);
308     RSPADDR
309     RSPHEAD
310     *rspa = rAddI (*rspa, OPENISIS_RSP_DBID, sdbid, !0);
311     *rspa = rAddI (*rspa, OPENISIS_RSP_ERR, err, !0);
312     RSPDB
313     DELIVER
314     }
315    
316     static int _RqsMount (
317     int sst[], const char *dbn, Rec **rspa, LdspDlvCb *cb, void *cld
318     ) {
319     RSPVAR
320     GETDB("mount")
321     RSPADDR
322     RSPHEAD
323     sMsg (LOG_VERBOSE, "ldsp: _RqsMount %s from %d/%d",
324     dbn, sst[ISID], sst[ISER]);
325     RSPNOERR
326     RSPDB
327     RSPFDT
328     DELIVER
329     }
330    
331     static int _RqsMaxrow (
332     int sst[], const char *dbn, int flags,
333     Rec **rspa, LdspDlvCb *cb, void *cld
334     ) {
335     RSPVAR
336     int maxrow;
337     GETDB("maxrow")
338     maxrow = dMaxId (sdbid);
339     if (0 > maxrow) {
340     int rt = _RqsError (sst, ERR_TRASH, rspa, cb, cld, "maxrow",
341     "no maxrow for %s", dbn);
342     RSPFREE
343     return rt;
344     }
345     RSPADDR
346     RSPHEAD
347     sMsg (LOG_VERBOSE, "ldsp: _RqsMaxrow %s from %d/%d",
348     dbn, sst[ISID], sst[ISER]);
349     RSPNOERR
350     RSPDB
351     if (OPENISIS_RQSF_MNT & flags) {
352     RSPFDT
353     }
354     *rspa = rAddI (*rspa, OPENISIS_COM_ROW, maxrow, !0);
355     DELIVER
356     }
357    
358     static int _RqsQuery (
359     int sst[], const char *dbn, const char *key, int mode, int skip,
360     int size, int flags, Rec **rspa, LdspDlvCb *cb, void *cld
361     ) {
362     RSPVAR
363     Set set;
364     Rec *rec;
365     int lrt;
366     int j;
367     int rdr = OPENISIS_RQSF_QRR & flags;
368     GETDB("query")
369     sMsg (LOG_VERBOSE, "ldsp: _RqsQuery %s from %d/%d",
370     dbn, sst[ISID], sst[ISER]);
371     set.len = 0; /* input */
372     lrt = dQuery (&set, sdbid, key, mode, skip);
373     if (0 > lrt) {
374     int rt = _RqsError (sst, ERR_TRASH, rspa, cb, cld, "query",
375     "%d,%s = %d", sdbid, key, lrt);
376     return rt;
377     }
378     RSPADDR
379     RSPHEAD
380     RSPNOERR
381     RSPDB
382     if (OPENISIS_RQSF_MNT & flags) {
383     RSPFDT
384     }
385     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMT, lrt, !0);
386     if (0 < size && lrt > size) {
387     lrt = size;
388     }
389     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMR, lrt, !0);
390     for (j = 0; lrt > j; ++j) {
391     *rspa = rAddI (*rspa, OPENISIS_COM_ROW, set.id[j], !0);
392     }
393     if (rdr) {
394     for (j = 0; *rspa && lrt > j; ++j) {
395     rec = dRead (sdbid, set.id[j]);
396     if (rec) {
397     UTF8REC (rec, 0, "query")
398     }
399     else {
400     sMsg (ERR_TRASH | LOG_WARN,
401     "db %s: non-existent mfn %d for key %s",
402     dbn, set.id[j], key);
403     rec = rDup (0, 0, 0);
404     }
405     *rspa = luti_wrap (*rspa, rec, OPENISIS_COM_REC);
406     mFree (rec);
407     }
408     }
409     DELIVER
410     }
411    
412     static int _RqsRead (
413     int sst[], const char *dbn, int row, int flags,
414     Rec **rspa, LdspDlvCb *cb, void *cld
415     ) {
416     RSPVAR
417     Rec *rec;
418     GETDB("read")
419     RSPADDR
420     RSPHEAD
421     sMsg (LOG_VERBOSE, "ldsp: _RqsRead %s %d from %d/%d",
422     dbn, row, sst[ISID], sst[ISER]);
423     RSPNOERR
424     RSPDB
425     if (OPENISIS_RQSF_MNT & flags) {
426     RSPFDT
427     }
428     rec = dRead (sdbid, row);
429     if (rec) {
430     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMT, 1, !0);
431     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMR, 1, !0);
432     *rspa = rAddI (*rspa, OPENISIS_COM_ROW, row, !0);
433     UTF8REC (rec, 0, "read")
434     *rspa = luti_wrap (*rspa, rec, OPENISIS_COM_REC);
435     mFree (rec);
436     }
437     else {
438     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMT, 0, !0);
439     *rspa = rAddI (*rspa, OPENISIS_RSP_NUMR, 0, !0);
440     }
441     DELIVER
442     }
443    
444     static int _RqsUpdate (
445     int sst[], const char *dbn, int row, Rec *rec, Rec *idx, int flags,
446     Rec **rspa, LdspDlvCb *cb, void *cld
447     ) {
448     RSPVAR
449     int rtw;
450     GETDB("update")
451     sMsg (LOG_VERBOSE, "ldsp: _RqsUpdate %s %d from %d/%d",
452     dbn, row, sst[ISID], sst[ISER]);
453     if (rec) {
454     rec->rowid = row;
455     rec->dbid = sdbid;
456     UTF8REC (rec, !0, "update")
457     }
458     rtw = dWritex (sdbid, rec, idx);
459     if (rtw) {
460     rtw = _RqsError (sst, ERR_TRASH, rspa, cb, cld,
461     "update", "write error %d", rtw);
462     mFree (rec);
463     mFree (idx);
464     return rtw;
465     }
466     RSPADDR
467     RSPHEAD
468     RSPNOERR
469     RSPDB
470     if (OPENISIS_RQSF_MNT & flags) {
471     RSPFDT
472     }
473     if (rec) {
474     row = rec->rowid;
475     mFree (rec);
476     }
477     mFree (idx);
478     *rspa = rAddI (*rspa, OPENISIS_COM_ROW, row, !0);
479     DELIVER
480     }
481    
482     static int _RqsDelete (
483     int sst[], const char *dbn, int row, int flags,
484     Rec **rspa, LdspDlvCb *cb, void *cld
485     ) {
486     (void)flags;
487     sMsg (LOG_VERBOSE, "ldsp: _RqsDelete %s %d from %d/%d",
488     dbn, row, sst[ISID], sst[ISER]);
489     return _RqsError (sst, ERR_TRASH, rspa, cb, cld, "delete",
490     "request not implemented yet");
491     }
492    
493     /* ************************************************************
494     package functions
495     */
496    
497     int ldspProcess (Rec *rqs, Rec **rspa, LdspDlvCb *cb, void *cld) {
498     char buf[PATH_MAX];
499     char *dbn = 0;
500     int sst[SSTS];
501     int rtyp;
502     int flags = 0;
503    
504     if (0 == rqs) {
505     return sMsg (ERR_IDIOT, "ldspProcess: no request");
506     }
507     if (0 == rspa && 0 == cb) {
508     return sMsg (ERR_IDIOT, "ldspProcess: no callback");
509     }
510    
511     rtyp = rInt (rqs, OPENISIS_RQS_TYPE, -1, 0);
512     sst[ISID] = rInt (rqs, OPENISIS_COM_SID, -1, 0);
513     sst[ISER] = rInt (rqs, OPENISIS_COM_SER, -1, 0);
514     sst[ITMS] = rInt (rqs, OPENISIS_COM_TMS, -1, 0);
515    
516     if (OPENISIS_RQST_LSDB != rtyp &&
517     OPENISIS_RQST_EVAL != rtyp
518     ) {
519     dbn = rString (rqs, OPENISIS_COM_DBN, 0, buf, sizeof(buf));
520     if (!dbn) {
521     i2a (buf, rtyp);
522     return _RqsError (sst, ERR_INVAL, rspa, cb, cld, buf,
523     "no db name given");
524     }
525     flags = rInt (rqs, OPENISIS_RQS_FLG, 0, 0);
526     }
527    
528     switch (rtyp) {
529    
530     case OPENISIS_RQST_LSDB:
531     return _RqsLsDb (sst, rspa, cb, cld);
532    
533     case OPENISIS_RQST_OPEN: {
534     Rec *dbpar = luti_unwrap (rqs, 0, OPENISIS_COM_CFG, -1);
535     Fdt *fdt = fRec2Fdt (rqs);
536     return _RqsOpen (sst, dbn, dbpar, fdt, rspa, cb, cld);
537     }
538    
539     case OPENISIS_RQST_CLOS:
540     return _RqsClose (sst, dbn, rspa, cb, cld);
541    
542     case OPENISIS_RQST_MNT:
543     return _RqsMount (sst, dbn, rspa, cb, cld);
544    
545     case OPENISIS_RQST_MROW:
546     return _RqsMaxrow (sst, dbn, flags, rspa, cb, cld);
547    
548     case OPENISIS_RQST_QRY: {
549     char kybuf[OPENISIS_QRY_KEYLEN];
550     char *key;
551     int mode, skip, size;
552     key = rString (rqs, OPENISIS_RQS_KEY, 0, kybuf, OPENISIS_QRY_KEYLEN);
553     mode = rInt (rqs, OPENISIS_RQS_QMOD, -1, 0);
554     skip = rInt (rqs, OPENISIS_RQS_SKIP, 0, 0);
555     size = rInt (rqs, OPENISIS_RQS_SIZE, -1, 0);
556     if (0 > mode || 0 == key) {
557     return _RqsError (sst, ERR_INVAL, rspa, cb, cld, "query",
558     "missing mode or key");
559     }
560     return _RqsQuery (sst, dbn, key,
561     mode, skip, size, flags, rspa, cb, cld);
562     }
563    
564     case OPENISIS_RQST_READ: {
565     int rowid;
566     rowid = rInt (rqs, OPENISIS_COM_ROW, -1, 0);
567     if (0 > rowid) {
568     return _RqsError (sst, ERR_INVAL, rspa, cb, cld, "read",
569     "missing rowid");
570     }
571     return _RqsRead (sst, dbn, rowid, flags, rspa, cb, cld);
572     }
573    
574     case OPENISIS_RQST_INS:
575     case OPENISIS_RQST_UPD: {
576     Rec *rec, *idx;
577     int rowid = 0;
578     int ins = rtyp == OPENISIS_RQST_INS;
579     rec = luti_unwrap (rqs, 0, OPENISIS_COM_REC, -1);
580     idx = luti_unwrap (rqs, 0, OPENISIS_RQS_IDX, -1);
581     if (!(rec || idx)) {
582     return _RqsError (sst, ERR_INVAL, rspa, cb, cld,
583     "update", "missing record or index");
584     }
585     rowid = rInt (rqs, OPENISIS_COM_ROW, 0, 0);
586     if (! ins && 0 >= rowid) {
587     return _RqsError (sst, ERR_INVAL, rspa, cb, cld,
588     "update", "missing rowid");
589     }
590     return _RqsUpdate (sst, dbn, rowid, rec, idx, flags, rspa, cb, cld);
591     }
592    
593     case OPENISIS_RQST_DEL: {
594     int rowid;
595     rowid = rInt (rqs, OPENISIS_COM_ROW, -1, 0);
596     if (0 > rowid) {
597     return _RqsError (sst, ERR_INVAL, rspa, cb, cld, "delete",
598     "missing rowid");
599     }
600     return _RqsDelete (sst, dbn, rowid, flags, rspa, cb, cld);
601     }
602    
603     case OPENISIS_RQST_EVAL: {
604     Rec *rec;
605     rec = luti_unwrap (rqs, 0, OPENISIS_COM_REC, -1);
606     if (! rec) {
607     return _RqsError (sst, ERR_INVAL, rspa, cb, cld,
608     "eval", "missing command record");
609     }
610     return _RqsEval (sst, rec, rspa, cb, cld);
611     }
612    
613     } /* switch */
614    
615     i2a (buf, rtyp);
616     return _RqsError (sst, ERR_INVAL, rspa, cb, cld, buf,
617     "unrecognized request type");
618     } /* ldspProcess */
619    

  ViewVC Help
Powered by ViewVC 1.1.26