Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / gdp / gdp_api.c @ master

History | View | Annotate | Download (24.8 KB)

1 cd2ef2a6 Eric Allman
/* vim: set ai sw=4 sts=4 ts=4 :*/
2
3 055d3009 Eric Allman
/*
4
**        This implements the GDP API for C-based applications.
5
**
6
**  With the exception of the name manipulation (parsing,
7
**  printing, etc.) most of these are basically just translation
8
**  routines, converting the API calls into requests and handing
9 eae1d3ec Eric Allman
**  them on; the hard work is done in gdp_gob_ops.c and gdp_proto.c.
10 055d3009 Eric Allman
**
11
**        TODO In the future this may need to be extended to have knowledge
12
**                 of TSN/AVB, but for now we don't worry about that.
13
**
14
**        ----- BEGIN LICENSE BLOCK -----
15
**        GDP: Global Data Plane Support Library
16
**        From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
17
**
18 c87dd166 Eric Allman
**        Copyright (c) 2015-2019, Regents of the University of California.
19 6bd5476b Eric Allman
**        All rights reserved.
20 055d3009 Eric Allman
**
21 6bd5476b Eric Allman
**        Permission is hereby granted, without written agreement and without
22
**        license or royalty fees, to use, copy, modify, and distribute this
23
**        software and its documentation for any purpose, provided that the above
24
**        copyright notice and the following two paragraphs appear in all copies
25
**        of this software.
26 055d3009 Eric Allman
**
27 6bd5476b Eric Allman
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
28
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
29
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
30
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 055d3009 Eric Allman
**
32 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
33 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 6bd5476b Eric Allman
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
35
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
36
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
37
**        OR MODIFICATIONS.
38 055d3009 Eric Allman
**        ----- END LICENSE BLOCK -----
39
*/
40
41 343366c2 Eric Allman
#include "gdp.h"
42 3bc20136 Eric Allman
#include "gdp_chan.h"
43 fec93aac Eric Allman
#include "gdp_event.h"
44 eae1d3ec Eric Allman
#include "gdp_md.h"
45 343366c2 Eric Allman
#include "gdp_stat.h"
46
#include "gdp_priv.h"
47
48 5a73c6ad Eric Allman
#include <ep/ep_app.h>
49
#include <ep/ep_b64.h>
50
#include <ep/ep_dbg.h>
51 b2910e9d Eric Allman
#include <ep/ep_funclist.h>
52 5a73c6ad Eric Allman
#include <ep/ep_prflags.h>
53
#include <ep/ep_string.h>
54
55 ecbc8f12 Eric Allman
#include <openssl/sha.h>
56 343366c2 Eric Allman
57 cd2ef2a6 Eric Allman
#include <errno.h>
58 22442bd4 Eric Allman
#include <string.h>
59 cd2ef2a6 Eric Allman
60
static EP_DBG        Dbg = EP_DBG_INIT("gdp.api", "C API for GDP");
61
62 fec93aac Eric Allman
static EP_THR_MUTEX                GinFreeListMutex        EP_THR_MUTEX_INITIALIZER;
63
SLIST_HEAD(gin_list_head, gdp_gin)
64
                                                GinFreeList                        = SLIST_HEAD_INITIALIZER(GinFreeList);
65
66 cd2ef2a6 Eric Allman
67 1aa4fc2c Eric Allman
/*
68
**  Mutex around open operations
69
*/
70
71 6dfc87d5 Eric Allman
static EP_THR_MUTEX                OpenMutex                EP_THR_MUTEX_INITIALIZER;
72 1aa4fc2c Eric Allman
73
74 ddb857b7 Eric Allman
/*
75
**  Simplify debugging
76
*/
77
78
static void
79 fec93aac Eric Allman
prstat(EP_STAT estat, const gdp_gin_t *gin, const char *where)
80 ddb857b7 Eric Allman
{
81
        int dbglev = 2;
82
        char ebuf[100];
83
84
        if (EP_STAT_ISOK(estat))
85
                dbglev = 39;
86
        else if (EP_STAT_ISWARN(estat))
87
                dbglev = 11;
88 fec93aac Eric Allman
        if (gin == NULL || gin->gob == NULL)
89 ddb857b7 Eric Allman
        {
90
                ep_dbg_cprintf(Dbg, dbglev, "<<< %s: %s\n",
91
                                where, ep_stat_tostr(estat, ebuf, sizeof ebuf));
92
        }
93
        else
94
        {
95
                ep_dbg_cprintf(Dbg, dbglev, "<<< %s(%s): %s\n",
96 fec93aac Eric Allman
                                where, gin->gob->pname,
97
                                ep_stat_tostr(estat, ebuf, sizeof ebuf));
98 ddb857b7 Eric Allman
        }
99
}
100
101 fec93aac Eric Allman
102
/*
103
**  Generic GDP Object Instance (GIN) code.
104
*/
105
106 ddb857b7 Eric Allman
static EP_STAT
107 fec93aac Eric Allman
bad_gin(const gdp_gin_t *gin, const char *where, const char *xtra)
108 ddb857b7 Eric Allman
{
109
        EP_STAT estat;
110 fec93aac Eric Allman
        char wbuf[256];
111 ddb857b7 Eric Allman
112 fec93aac Eric Allman
        if (where != NULL && xtra != NULL)
113
        {
114
                snprintf(wbuf, sizeof wbuf, "%s/%s", where, xtra);
115
                where = wbuf;
116
        }
117
        if (gin == NULL)
118 eae1d3ec Eric Allman
                estat = GDP_STAT_NULL_GIN;
119 ddb857b7 Eric Allman
        else
120 92243bf4 Eric Allman
                estat = GDP_STAT_LOG_NOT_OPEN;
121 fec93aac Eric Allman
        prstat(estat, gin, where);
122 ddb857b7 Eric Allman
        return estat;
123
}
124 8701c522 Eric Allman
125 fec93aac Eric Allman
void
126
_gdp_gin_lock_trace(gdp_gin_t *gin,
127
                                        const char *file,
128
                                        int line,
129
                                        const char *id)
130
{
131
        _ep_thr_mutex_lock(&gin->mutex, file, line, id);
132 c9f4745b Eric Allman
        gin->flags |= GINF_ISLOCKED;
133 fec93aac Eric Allman
}
134
135
void
136
_gdp_gin_unlock_trace(gdp_gin_t *gin,
137
                                        const char *file,
138
                                        int line,
139
                                        const char *id)
140
{
141 c9f4745b Eric Allman
        gin->flags &= ~GINF_ISLOCKED;
142 fec93aac Eric Allman
        _ep_thr_mutex_unlock(&gin->mutex, file, line, id);
143
}
144
145 c9f4745b Eric Allman
146 75f25465 Eric Allman
static EP_PRFLAGS_DESC        _GdpGinFlags[] =
147 c9f4745b Eric Allman
{
148
        { GINF_INUSE,                                GINF_INUSE,                        "INUSE"                                },
149
        { GINF_ISLOCKED,                        GINF_ISLOCKED,                "ISLOCKED"                        },
150 ee0cddb9 Eric Allman
        { GINF_SIG_VRFY,                        GINF_SIG_VRFY,                "SIG_VRFY"                        },
151
        { GINF_SIG_VRFY_REQ,                GINF_SIG_VRFY_REQ,        "SIG_VRFY_REQ"                },
152 c9f4745b Eric Allman
        { 0, 0, NULL }
153
};
154
155 c9b75ebc Eric Allman
void
156
_gdp_gin_dump(
157
                const gdp_gin_t *gin,
158
                FILE *fp,
159
                int detail)
160
{
161 8bebf0e3 Eric Allman
        int indent = 1;
162 c9b75ebc Eric Allman
163
        if (fp == NULL)
164
                fp = ep_dbg_getfile();
165
        if (detail >= GDP_PR_BASIC)
166
                fprintf(fp, "GIN@%p: ", gin);
167
        VALGRIND_HG_DISABLE_CHECKING(gin, sizeof *gin);
168
        if (gin == NULL)
169
        {
170
                fprintf(fp, "NULL\n");
171
        }
172
        else
173
        {
174
                gdp_gob_t *gob = gin->gob;
175
176
                if (gob == NULL)
177
                        fprintf(fp, "No GOB\n");
178
                else
179
                {
180
                        VALGRIND_HG_DISABLE_CHECKING(gob, sizeof *gob);
181
                        if (!gdp_name_is_valid(gob->name))
182
                                fprintf(fp, "no name\n");
183
                        else
184
                                fprintf(fp, "%s\n", gob->pname);
185
                        VALGRIND_HG_ENABLE_CHECKING(gob, sizeof *gob);
186
                }
187 8bebf0e3 Eric Allman
                fprintf(fp, "%sflags = ", _gdp_pr_indent(indent));
188 75f25465 Eric Allman
                ep_prflags(gin->flags, _GdpGinFlags, fp);
189 c9b75ebc Eric Allman
190
                if (detail >= GDP_PR_BASIC)
191
                {
192 8bebf0e3 Eric Allman
                        fprintf(fp, "\n%sgob = %p, iomode = %d",
193
                                        _gdp_pr_indent(indent), gob,  gin->iomode);
194 c9b75ebc Eric Allman
                        if (detail >= GDP_PR_DETAILED)
195
                        {
196
                                fprintf(fp, ", closefunc = %p\n"
197 8bebf0e3 Eric Allman
                                                "%sapndfilter = %p, apndfpriv = %p,"
198 c9b75ebc Eric Allman
                                                " readfilter = %p, readfpriv = %p",
199
                                                gin->closefunc,
200 8bebf0e3 Eric Allman
                                                _gdp_pr_indent(indent),
201 c9b75ebc Eric Allman
                                                gin->apndfilter, gin->apndfpriv,
202
                                                gin->readfilter, gin->readfpriv);
203
                        }
204
                }
205
                fprintf(fp, "\n");
206
        }
207
        VALGRIND_HG_ENABLE_CHECKING(gin, sizeof *gin);
208
}
209
210 31d6906f Eric Allman
static void
211
unlock_gin_and_gob(gdp_gin_t *gin, const char *where)
212
{
213
        _gdp_gob_unlock(gin->gob);
214
        _gdp_gin_unlock(gin);
215
}
216
217 fec93aac Eric Allman
static EP_STAT
218
check_and_lock_gin(gdp_gin_t *gin, const char *where)
219
{
220
        if (gin == NULL)
221
                return bad_gin(gin, where, "null gin");
222
        _gdp_gin_lock(gin);
223 c9f4745b Eric Allman
        if (!EP_UT_BITSET(GINF_INUSE, gin->flags))
224 fec93aac Eric Allman
        {
225
                _gdp_gin_unlock(gin);
226
                return bad_gin(gin, where, "gin not inuse");
227
        }
228
        if (gin->gob == NULL)
229
        {
230
                _gdp_gin_unlock(gin);
231
                return bad_gin(gin, where, "null gob");
232
        }
233
        return EP_STAT_OK;
234
}
235
236
static EP_STAT
237
check_and_lock_gin_and_gob(gdp_gin_t *gin, const char *where)
238
{
239
        EP_STAT estat;
240
241
        estat = check_and_lock_gin(gin, where);
242
        EP_STAT_CHECK(estat, return estat);
243
        _gdp_gob_lock(gin->gob);
244 eae1d3ec Eric Allman
        if (!EP_UT_BITSET(GOBF_INUSE, gin->gob->flags))
245 4a6db795 Eric Allman
                estat = bad_gin(gin, where, "gob not inuse");
246 eae1d3ec Eric Allman
        else if (EP_UT_BITSET(GOBF_DROPPING, gin->gob->flags))
247 4a6db795 Eric Allman
                estat = bad_gin(gin, where, "gob not open");
248
        else if (gin->gob->refcnt <= 0)
249
                estat = bad_gin(gin, where, "gob bad refcnt");
250
        if (!EP_STAT_ISOK(estat))
251 31d6906f Eric Allman
                unlock_gin_and_gob(gin, "check_and_lock_gin_and_gob");
252 4a6db795 Eric Allman
        return estat;
253 fec93aac Eric Allman
}
254
255
256
/*
257 eae1d3ec Eric Allman
**  Allocate and Free GDP Object Instance handles.
258 6188de9e Eric Allman
**
259
**                Note that the reference count on the input GOB is not
260
**                increased; it is assumed that the GIN "takes over" the
261
**                reference that is passed in.
262 fec93aac Eric Allman
*/
263
264
gdp_gin_t *
265
_gdp_gin_new(gdp_gob_t *gob)
266
{
267
        gdp_gin_t *gin = NULL;
268
269
        for (;;)
270
        {
271
                ep_thr_mutex_lock(&GinFreeListMutex);
272
                if ((gin = SLIST_FIRST(&GinFreeList)) != NULL)
273
                        SLIST_REMOVE_HEAD(&GinFreeList, next);
274
                ep_thr_mutex_unlock(&GinFreeListMutex);
275 c9f4745b Eric Allman
                if (gin == NULL || !EP_UT_BITSET(GINF_INUSE, gin->flags))
276 fec93aac Eric Allman
                        break;
277
278
                // gin from freelist is allocated --- abandon it
279
                EP_ASSERT_PRINT("_gdp_gin_new: allocated gin %p on free list", gin);
280
        }
281
282
        if (gin == NULL)
283
        {
284 fc0cbc23 Eric Allman
                gin = (gdp_gin_t *) ep_mem_zalloc(sizeof *gin);
285 fec93aac Eric Allman
                ep_thr_mutex_init(&gin->mutex, EP_THR_MUTEX_DEFAULT);
286
                ep_thr_mutex_setorder(&gin->mutex, GDP_MUTEX_LORDER_GIN);
287
        }
288
289 c9f4745b Eric Allman
        gin->flags = GINF_INUSE;
290 80da996e Eric Allman
        gin->iomode = GDP_MODE_ANY;
291 fec93aac Eric Allman
        gin->gob = gob;
292
293
        VALGRIND_HG_CLEAN_MEMORY(gin, sizeof gin);
294
        ep_dbg_cprintf(Dbg, 48, "_gdp_gin_new => %p\n", gin);
295
        return gin;
296
}
297
298
void
299
_gdp_gin_free(gdp_gin_t *gin)
300
{
301
        ep_dbg_cprintf(Dbg, 28, "_gdp_gin_free(%p)\n", gin);
302
        if (gin == NULL)
303
                return;
304 c9f4745b Eric Allman
        if (!EP_ASSERT(EP_UT_BITSET(GINF_INUSE, gin->flags)))
305 fec93aac Eric Allman
                return;
306
        GDP_GIN_ASSERT_ISLOCKED(gin);
307 8701c522 Eric Allman
308 4a6db795 Eric Allman
        // release resources: requests (subscriptions) and events
309 fec93aac Eric Allman
        if (gin->gob != NULL)
310
        {
311
                GDP_GOB_ASSERT_ISLOCKED(gin->gob);
312 4a6db795 Eric Allman
                _gdp_req_freeall(gin->gob, gin, NULL);
313 fec93aac Eric Allman
                _gdp_gob_decref(&gin->gob, false);
314
        }
315 4a6db795 Eric Allman
        _gdp_event_free_all(gin);
316 fec93aac Eric Allman
317
        // put gin handle on freelist
318
        ep_thr_mutex_lock(&GinFreeListMutex);
319 4a6db795 Eric Allman
        gin->flags = 0;
320 fec93aac Eric Allman
        SLIST_INSERT_HEAD(&GinFreeList, gin, next);
321
        _gdp_gin_unlock(gin);
322
        ep_thr_mutex_unlock(&GinFreeListMutex);
323
}
324 1ca7751e Eric Allman
325 cd2ef2a6 Eric Allman
326
/*
327 eae1d3ec Eric Allman
**        GDP_GIN_GETNAME --- get the name of a GDP log
328 cd2ef2a6 Eric Allman
*/
329
330 549b367d Eric Allman
const gdp_name_t *
331 eae1d3ec Eric Allman
gdp_gin_getname(const gdp_gin_t *gin)
332 cd2ef2a6 Eric Allman
{
333 fec93aac Eric Allman
        if (!GDP_GIN_ISGOOD(gin))
334 ddb857b7 Eric Allman
        {
335 eae1d3ec Eric Allman
                (void) bad_gin(gin, "gdp_gin_getname", NULL);
336 ddb857b7 Eric Allman
                return NULL;
337
        }
338 fec93aac Eric Allman
        return &gin->gob->name;
339 cd2ef2a6 Eric Allman
}
340
341
342
/*
343 eae1d3ec Eric Allman
**  GDP_GIN_GETNRECS --- get the number of records in a GOB
344 9c59e638 Eric Allman
*/
345
346
gdp_recno_t
347 eae1d3ec Eric Allman
gdp_gin_getnrecs(const gdp_gin_t *gin)
348 9c59e638 Eric Allman
{
349 fec93aac Eric Allman
        if (!GDP_GIN_ISGOOD(gin))
350 ddb857b7 Eric Allman
        {
351 eae1d3ec Eric Allman
                (void) bad_gin(gin, "gdp_gin_getnrecs", NULL);
352 ddb857b7 Eric Allman
                return GDP_PDU_NO_RECNO;
353
        }
354 fec93aac Eric Allman
        return gin->gob->nrecs;
355 9c59e638 Eric Allman
}
356
357
358 cd2ef2a6 Eric Allman
/*
359 eae1d3ec Eric Allman
**  GDP_GIN_PRINT --- print a GOB (for debugging)
360 cd2ef2a6 Eric Allman
*/
361
362
void
363 eae1d3ec Eric Allman
gdp_gin_print(
364
                const gdp_gin_t *gin,
365 4102ad3a Eric Allman
                FILE *fp)
366 cd2ef2a6 Eric Allman
{
367 fec93aac Eric Allman
        if (!GDP_GIN_ISGOOD(gin))
368
        {
369
                (void) bad_gin(gin, "gdp_gin_print", NULL);
370
        }
371
        else
372
        {
373
                // _gdp_gob_dump handles null gob properly
374
                _gdp_gob_dump(gin->gob, fp, GDP_PR_PRETTY, 0);
375
        }
376 cd2ef2a6 Eric Allman
}
377
378
379
380
/*
381
**        GDP_INIT --- initialize this library
382 7a52336b Eric Allman
**
383
**                This is the normal startup for a client process.  Servers
384
**                may need to do additional steps early on, and may choose
385
**                to advertise more than their own name.
386 cd2ef2a6 Eric Allman
*/
387
388 f678e274 Eric Allman
static void
389
gdp_exit_debug(void)
390
{
391
        if (ep_dbg_test(Dbg, 10))
392
        {
393
                _gdp_req_pr_stats(ep_dbg_getfile());
394 fec93aac Eric Allman
                _gdp_gob_pr_stats(ep_dbg_getfile());
395 f678e274 Eric Allman
        }
396
}
397
398 866c2ca2 Eric Allman
399 cd2ef2a6 Eric Allman
EP_STAT
400 7a52336b Eric Allman
gdp_init(const char *router_addr)
401 cd2ef2a6 Eric Allman
{
402 866c2ca2 Eric Allman
        return gdp_init2(router_addr, 0);
403
}
404
405
406
EP_STAT
407
gdp_init2(const char *router_addr, uint32_t flags)
408
{
409 fc0cbc23 Eric Allman
        gdp_chan_x_t *chanx = NULL;
410 5a73c6ad Eric Allman
        EP_STAT estat = EP_STAT_OK;
411 b2910e9d Eric Allman
        extern EP_FUNCLIST *_GdpDumpFuncs;
412 0314a7a7 Eric Allman
413 866c2ca2 Eric Allman
        ep_dbg_cprintf(Dbg, 9, "gdp_init, state = %d\n", _GdpInitState);
414
        if (_GdpInitState >= GDP_INIT_COMPLETE)
415 5a73c6ad Eric Allman
                goto done;
416 0314a7a7 Eric Allman
417 5a73c6ad Eric Allman
        // set up global state, event loop, etc. (shared with gdplogd)
418 866c2ca2 Eric Allman
        if (_GdpInitState < GDP_INIT_LIB)
419
        {
420
                estat = gdp_lib_init(NULL, NULL, flags);
421
                EP_STAT_CHECK(estat, goto fail0);
422
        }
423 54e73f13 Eric Allman
424 b2910e9d Eric Allman
        ep_funclist_push(_GdpDumpFuncs, _gdp_event_dump_all, NULL);
425
426 fc0cbc23 Eric Allman
        chanx = (gdp_chan_x_t *) ep_mem_zalloc(sizeof *chanx);
427 f2bf61a4 Eric Allman
        LIST_INIT(&chanx->reqs);
428
429 5a73c6ad Eric Allman
        // open at least one channel to the routing subsystem
430 857ddc7c Eric Allman
        _GdpChannel = NULL;
431 5a73c6ad Eric Allman
        estat = _gdp_chan_open(router_addr,                        // IP of router
432
                                                NULL,                                        // qos (unused as yet)
433
                                                &_gdp_io_recv,                        // receive callback
434
                                                NULL,                                        // send callback
435
                                                &_gdp_io_event,                        // close/error/eof callback
436 d65c01e2 Eric Allman
                                                &_gdp_router_event,                // router event callback
437 5a73c6ad Eric Allman
                                                &_gdp_advertise_me,                // advertise callback
438 d65c01e2 Eric Allman
                                                chanx,                                        // user channel data
439 5a73c6ad Eric Allman
                                                &_GdpChannel);                        // output: new channel
440 08709feb Eric Allman
        EP_STAT_CHECK(estat, goto fail0);
441 54e73f13 Eric Allman
442 f2bf61a4 Eric Allman
        if (ep_thr_spawn(&_GdpIoEventLoopThread, &_gdp_run_event_loop, NULL) != 0)
443 54e73f13 Eric Allman
        {
444 5a73c6ad Eric Allman
                char ebuf[100];
445
446
                estat = ep_stat_from_errno(errno);
447
                ep_app_severe("cannot spawn event i/o thread: %s",
448
                                        ep_stat_tostr(estat, ebuf, sizeof ebuf));
449 54e73f13 Eric Allman
        }
450
451 f678e274 Eric Allman
        // do some optional status printing on exit
452
        atexit(gdp_exit_debug);
453
454 866c2ca2 Eric Allman
        _GdpInitState = GDP_INIT_COMPLETE;
455 2cdd45bd Eric Allman
456 54e73f13 Eric Allman
fail0:
457 5a73c6ad Eric Allman
done:
458
        if (ep_dbg_test(Dbg, 4))
459 54e73f13 Eric Allman
        {
460
                char ebuf[200];
461
462 5a73c6ad Eric Allman
                ep_dbg_printf("gdp_init: %s\n",
463
                                        ep_stat_tostr(estat, ebuf, sizeof ebuf));
464 54e73f13 Eric Allman
        }
465
        return estat;
466 cd2ef2a6 Eric Allman
}
467
468
469
/*
470 eae1d3ec Eric Allman
**        GDP_GIN_OPEN --- open a GOB for reading or further appending
471 cd2ef2a6 Eric Allman
*/
472
473
EP_STAT
474 eae1d3ec Eric Allman
gdp_gin_open(gdp_name_t name,
475 11029b9c Eric Allman
                        gdp_iomode_t iomode,
476 eae1d3ec Eric Allman
                        gdp_open_info_t *open_info,
477
                        gdp_gin_t **pgin)
478 cd2ef2a6 Eric Allman
{
479 a7ab7f37 Eric Allman
        EP_STAT estat;
480 fec93aac Eric Allman
        gdp_gob_t *gob = NULL;
481 c9f4745b Eric Allman
        gdp_gin_t *gin = NULL;
482 f67d0170 Eric Allman
        gdp_cmd_t cmd;
483 cd2ef2a6 Eric Allman
484 195530a2 Eric Allman
        if (ep_dbg_test(Dbg, 19))
485
        {
486
                gdp_pname_t pname;
487 49d76189 Eric Allman
                ep_dbg_printf("\n>>> gdp_gin_open(%s)\n",
488 195530a2 Eric Allman
                                        gdp_printable_name(name, pname));
489
        }
490 a749564b Eric Allman
        estat = GDP_CHECK_INITIALIZED;                // make sure gdp_init is done
491
        EP_STAT_CHECK(estat, return estat);
492 b8c5e7c8 Eric Allman
493 11029b9c Eric Allman
        if (iomode == GDP_MODE_RO)
494 cd2ef2a6 Eric Allman
                cmd = GDP_CMD_OPEN_RO;
495 11029b9c Eric Allman
        else if (iomode == GDP_MODE_AO)
496 cd2ef2a6 Eric Allman
                cmd = GDP_CMD_OPEN_AO;
497 11029b9c Eric Allman
        else if (iomode == GDP_MODE_RA)
498 b48f4199 Eric Allman
                cmd = GDP_CMD_OPEN_RA;
499 cd2ef2a6 Eric Allman
        else
500
        {
501
                // illegal I/O mode
502 49d76189 Eric Allman
                ep_app_error("gdp_gin_open: illegal mode %d", iomode);
503 cd2ef2a6 Eric Allman
                return GDP_STAT_BAD_IOMODE;
504
        }
505
506 549b367d Eric Allman
        if (!gdp_name_is_valid(name))
507 cd2ef2a6 Eric Allman
        {
508 eae1d3ec Eric Allman
                // illegal GOB name
509 49d76189 Eric Allman
                ep_dbg_cprintf(Dbg, 6, "gdp_gin_open: null GOB name\n");
510 eae1d3ec Eric Allman
                return GDP_STAT_GDP_NAME_INVALID;
511 cd2ef2a6 Eric Allman
        }
512
513 eae1d3ec Eric Allman
        // lock this operation to keep the GOB cache consistent
514 1aa4fc2c Eric Allman
        ep_thr_mutex_lock(&OpenMutex);
515
516 1c492c37 Eric Allman
        // see if we already have this open (and initiate open if not)
517 fec93aac Eric Allman
        estat = _gdp_gob_cache_get(name, GGCF_CREATE, &gob);
518 11029b9c Eric Allman
        EP_STAT_CHECK(estat, goto fail0);
519 fec93aac Eric Allman
        EP_ASSERT(gob != NULL);
520
        GDP_GOB_ASSERT_ISLOCKED(gob);
521 11029b9c Eric Allman
522
        // if open is partially complete, finish the job
523 eae1d3ec Eric Allman
        if (EP_UT_BITSET(GOBF_PENDING, gob->flags))
524 e8097b09 Eric Allman
        {
525 fec93aac Eric Allman
                estat = _gdp_gob_open(gob, cmd, open_info, _GdpChannel, 0);
526 49d76189 Eric Allman
                if (EP_STAT_ISFAIL(estat))
527
                        goto fail0;
528 e8097b09 Eric Allman
        }
529 caef25cd Eric Allman
        gob->flags &= ~GOBF_PENDING;
530
        gin = _gdp_gin_new(gob);
531 11029b9c Eric Allman
532 caef25cd Eric Allman
        if (open_info != NULL)
533 cd2ef2a6 Eric Allman
        {
534 caef25cd Eric Allman
                if (EP_UT_BITSET(GOIF_VERIFY_PROOF, open_info->flags))
535
                {
536 ee0cddb9 Eric Allman
                        gin->flags |= GINF_SIG_VRFY;
537 caef25cd Eric Allman
                }
538 cd2ef2a6 Eric Allman
        }
539 fec93aac Eric Allman
        _gdp_gob_unlock(gob);
540 02de7463 Eric Allman
541 a7ab7f37 Eric Allman
fail0:
542 49d76189 Eric Allman
        // note that warnings are treated like success
543
        if (EP_STAT_ISFAIL(estat) && gob != NULL)
544 fec93aac Eric Allman
                _gdp_gob_free(&gob);
545 49d76189 Eric Allman
        *pgin = gin;                // might be NULL
546
547 1aa4fc2c Eric Allman
        ep_thr_mutex_unlock(&OpenMutex);
548 49d76189 Eric Allman
        prstat(estat, gin, "gdp_gin_open");
549 c9b75ebc Eric Allman
        if (ep_dbg_test(Dbg, 10))
550
        {
551 c9f4745b Eric Allman
                _gdp_gin_dump(gin, NULL, GDP_PR_DETAILED);
552 c9b75ebc Eric Allman
                if (ep_dbg_test(Dbg, 14))
553
                        _gdp_gob_dump(gob, NULL, GDP_PR_BASIC, 0);
554
        }
555 cd2ef2a6 Eric Allman
        return estat;
556
}
557
558
559
/*
560 eae1d3ec Eric Allman
**        GDP_GIN_CLOSE --- close an open GOB
561 cd2ef2a6 Eric Allman
*/
562
563
EP_STAT
564 eae1d3ec Eric Allman
gdp_gin_close(gdp_gin_t *gin)
565 cd2ef2a6 Eric Allman
{
566 f7307b63 Eric Allman
        EP_STAT estat;
567
568 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_close");
569 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
570 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 19, "\n>>> gdp_gin_close(%s)\n", gin->gob->pname);
571 4a6db795 Eric Allman
        estat = _gdp_gob_close(gin->gob, _GdpChannel, 0);
572 fec93aac Eric Allman
        _gdp_gin_free(gin);
573 eae1d3ec Eric Allman
        prstat(estat, gin, "gdp_gin_close");
574 f7307b63 Eric Allman
        return estat;
575 cd2ef2a6 Eric Allman
}
576
577
578
/*
579 eae1d3ec Eric Allman
**  GDP_GIN_DELETE --- delete and close an open GOB
580 4a6db795 Eric Allman
**
581
**                This is not intended to be an end-user API.  Deletion should
582
**                only be done by a system service on the basis of expiration
583
**                criteria.  This API is intended for testing.
584
*/
585
586
EP_STAT
587 eae1d3ec Eric Allman
gdp_gin_delete(gdp_gin_t *gin)
588 4a6db795 Eric Allman
{
589
        EP_STAT estat;
590
591 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_delete");
592 4a6db795 Eric Allman
        EP_STAT_CHECK(estat, return estat);
593 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 19, "\n>>> gdp_gin_delete(%s)\n", gin->gob->pname);
594 4a6db795 Eric Allman
        estat = _gdp_gob_delete(gin->gob, _GdpChannel, 0);
595
        _gdp_gin_free(gin);
596 eae1d3ec Eric Allman
        prstat(estat, gin, "gdp_gin_delete");
597 4a6db795 Eric Allman
        return estat;
598
}
599
600
601
/*
602 eae1d3ec Eric Allman
**        GDP_GIN_APPEND --- append a message to a writable GOB
603 cd2ef2a6 Eric Allman
*/
604
605
EP_STAT
606 eae1d3ec Eric Allman
gdp_gin_append(gdp_gin_t *gin, gdp_datum_t *datum, gdp_hash_t *prevhash)
607 cd2ef2a6 Eric Allman
{
608 6dfc87d5 Eric Allman
        EP_STAT estat;
609
610 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_append\n");
611 fec93aac Eric Allman
        if (!GDP_DATUM_ISGOOD(datum))
612
                return GDP_STAT_DATUM_REQUIRED;
613 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_append");
614 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
615
        if (gin->apndfilter != NULL)
616 08bc143f Eric Allman
                estat = gin->apndfilter(datum, gin->apndfpriv);
617 fec93aac Eric Allman
        if (EP_STAT_ISOK(estat))
618 4aa32996 Eric Allman
                estat = _gdp_gob_append_sync(gin->gob, 1, &datum, prevhash,
619 fa7cfdb9 Eric Allman
                                                                _GdpChannel, 0);
620 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_append");
621
        prstat(estat, gin, "gdp_gin_append");
622 6dfc87d5 Eric Allman
        return estat;
623 cd2ef2a6 Eric Allman
}
624
625
626
/*
627 eae1d3ec Eric Allman
**  GDP_GIN_APPEND_ASYNC --- asynchronously append to a writable GOB
628 e2682ba9 Eric Allman
*/
629
630
EP_STAT
631 eae1d3ec Eric Allman
gdp_gin_append_async(gdp_gin_t *gin,
632
                        int ndatums,
633
                        gdp_datum_t **datums,
634
                        gdp_hash_t *prevhash,
635 e2682ba9 Eric Allman
                        gdp_event_cbfunc_t cbfunc,
636
                        void *udata)
637
{
638 8701c522 Eric Allman
        EP_STAT estat;
639
640 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_append_async\n");
641
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_append_async");
642 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
643 4aa32996 Eric Allman
        estat = _gdp_gob_append_async(gin->gob, gin, ndatums, datums, prevhash,
644 fa7cfdb9 Eric Allman
                                                        cbfunc, udata, _GdpChannel, 0);
645 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_append_async");
646
        prstat(estat, gin, "gdp_gin_append_async");
647 8701c522 Eric Allman
        return estat;
648 e2682ba9 Eric Allman
}
649
650
651
/*
652 eae1d3ec Eric Allman
**        GDP_GIN_READ_BY_RECNO --- read a message from a GOB based on recno
653 cd2ef2a6 Eric Allman
**
654 932f745e Eric Allman
**        The data is returned through the passed-in datum.
655
**
656 cd2ef2a6 Eric Allman
**                Parameters:
657 eae1d3ec Eric Allman
**                        gin --- the GDP instance from which to read
658 cd2ef2a6 Eric Allman
**                        recno --- the record number to read
659 9509f13b Eric Allman
**                        datum --- the message header (to avoid dynamic memory)
660 cd2ef2a6 Eric Allman
*/
661
662
EP_STAT
663 eae1d3ec Eric Allman
gdp_gin_read_by_recno(gdp_gin_t *gin,
664 0314a7a7 Eric Allman
                        gdp_recno_t recno,
665 9509f13b Eric Allman
                        gdp_datum_t *datum)
666 cd2ef2a6 Eric Allman
{
667 8701c522 Eric Allman
        EP_STAT estat;
668 ee0cddb9 Eric Allman
        uint32_t reqflags = 0;
669 8701c522 Eric Allman
670 bd278f2e Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_read_by_recno (%"PRIgdp_recno ")\n",
671
                        recno);
672 ddb857b7 Eric Allman
        EP_ASSERT_POINTER_VALID(datum);
673 083cb865 Eric Allman
        gdp_datum_reset(datum);
674 65309098 Eric Allman
675 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_read_by_recno");
676 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
677 ee0cddb9 Eric Allman
678
        if (EP_UT_BITSET(GINF_SIG_VRFY, gin->flags))
679
                reqflags |= GDP_REQ_VRFY_CONTENT;
680 fec93aac Eric Allman
        //XXX somehow have to convey gin->readfilter to _gdp_gob_read
681
        //XXX is there any reason not to just do it here?
682
        //XXX Answer: read_async and subscriptions
683 ee0cddb9 Eric Allman
        estat = _gdp_gob_read_by_recno(gin->gob, recno, _GdpChannel,
684
                                                        reqflags, datum);
685 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_read_by_recno");
686
        prstat(estat, gin, "gdp_gin_read_by_recno");
687 8701c522 Eric Allman
        return estat;
688 65309098 Eric Allman
}
689
690
691
/*
692 eae1d3ec Eric Allman
**        GDP_GIN_READ_BY_TS --- read a message from a GOB based on timestamp
693 65309098 Eric Allman
**
694
**        The data is returned through the passed-in datum.
695
**
696
**                Parameters:
697 eae1d3ec Eric Allman
**                        gin --- the GDP instance from which to read
698 65309098 Eric Allman
**                        ts --- the lowest timestamp we are interested in.  The
699
**                                result will be the lowest timestamp that is greater than
700
**                                or equal to this value.
701
**                        datum --- the message header (to avoid dynamic memory)
702
*/
703
704
EP_STAT
705 eae1d3ec Eric Allman
gdp_gin_read_by_ts(gdp_gin_t *gin,
706 65309098 Eric Allman
                        EP_TIME_SPEC *ts,
707
                        gdp_datum_t *datum)
708
{
709 8701c522 Eric Allman
        EP_STAT estat;
710
711 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_read_by_ts\n");
712 ddb857b7 Eric Allman
        EP_ASSERT_POINTER_VALID(datum);
713 d65c01e2 Eric Allman
#if 0 //TODO
714
        memcpy(&datum->d->ts, ts, sizeof datum->d->ts);
715
        datum->d->recno = GDP_PDU_NO_RECNO;
716 9509f13b Eric Allman

717 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_read_by_ts");
718 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
719
        //XXX somehow have to convey gin->readfilter to _gdp_gob_read
720
        //XXX is there any reason not to just do it here?
721
        //XXX Answer: read_async and subscriptions
722
        estat = _gdp_gob_read(gin->gob, datum, _GdpChannel, 0);
723 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_read_by_ts");
724
        prstat(estat, gin, "gdp_gin_read_by_ts");
725 d65c01e2 Eric Allman
#else //TODO
726
        estat = GDP_STAT_NOT_IMPLEMENTED;
727
#endif //TODO
728 8701c522 Eric Allman
        return estat;
729 cd2ef2a6 Eric Allman
}
730
731
732
/*
733 eae1d3ec Eric Allman
**        GDP_GIN_READ_BY_HASH --- read a message from a GOB based on record hash
734 8204d4b2 Eric Allman
**
735 d65c01e2 Eric Allman
**        The data is returned through the passed-in datum.
736
**
737
**                Parameters:
738 eae1d3ec Eric Allman
**                        gin --- the GDP instance from which to read
739 d65c01e2 Eric Allman
**                        hash --- the starting record hash
740
**                        nrecs --- the number of records to read
741
**                        datum --- the message header (to avoid dynamic memory)
742 8204d4b2 Eric Allman
*/
743
744 d65c01e2 Eric Allman
#if 0 //TODO
745 8204d4b2 Eric Allman
EP_STAT
746 eae1d3ec Eric Allman
gdp_gin_read_by_hash(gdp_gin_t *gin,
747 d65c01e2 Eric Allman
                        ep_hash_t *hash,
748
                        gdp_datum_t *datum)
749
{
750
        EP_STAT estat;
751

752 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_read_by_hash\n");
753 d65c01e2 Eric Allman
        EP_ASSERT_POINTER_VALID(datum);
754
        memcpy(&datum->d->ts, ts, sizeof datum->d->ts);
755
        datum->d->recno = GDP_PDU_NO_RECNO;
756

757 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_read_by_hash");
758 d65c01e2 Eric Allman
        EP_STAT_CHECK(estat, return estat);
759
        //XXX somehow have to convey gin->readfilter to _gdp_gob_read
760
        //XXX is there any reason not to just do it here?
761
        //XXX Answer: read_async and subscriptions
762
        estat = _gdp_gob_read(gin->gob, datum, _GdpChannel, 0);
763 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_read_by_hash");
764
        prstat(estat, gin, "gdp_gin_read_by_hash");
765 d65c01e2 Eric Allman
        return estat;
766
}
767
#endif //TODO
768
769
770
/*
771 eae1d3ec Eric Allman
**  GDP_GIN_READ_BY_xxx_ASYNC --- read asynchronously
772 d65c01e2 Eric Allman
**
773
**  Data and status are delivered as events.  These subsume the
774
**  old multiread command.
775
*/
776
777
EP_STAT
778 eae1d3ec Eric Allman
gdp_gin_read_by_recno_async(
779
                        gdp_gin_t *gin,
780 8204d4b2 Eric Allman
                        gdp_recno_t recno,
781 d65c01e2 Eric Allman
                        int32_t nrecs,
782 8204d4b2 Eric Allman
                        gdp_event_cbfunc_t cbfunc,
783
                        void *cbarg)
784
{
785 8701c522 Eric Allman
        EP_STAT estat;
786
787 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_read_by_recno_async\n");
788
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_read_by_recno_async");
789 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
790 4aa32996 Eric Allman
        estat = _gdp_gob_read_by_recno_async(gin->gob, gin, recno, nrecs,
791 d65c01e2 Eric Allman
                                                        cbfunc, cbarg, _GdpChannel);
792 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_read_by_recno_async");
793
        prstat(estat, gin, "gdp_gin_read_by_recno_async");
794 8701c522 Eric Allman
        return estat;
795 8204d4b2 Eric Allman
}
796
797
798 d65c01e2 Eric Allman
EP_STAT
799 eae1d3ec Eric Allman
gdp_gin_read_by_ts_async(
800
                        gdp_gin_t *gin,
801 d65c01e2 Eric Allman
                        EP_TIME_SPEC *ts,
802
                        int32_t nrecs,
803
                        gdp_event_cbfunc_t cbfunc,
804
                        void *cbarg)
805
{
806
        return GDP_STAT_NOT_IMPLEMENTED;
807
}
808
809
810
EP_STAT
811 eae1d3ec Eric Allman
gdp_gin_read_by_hash_async(
812
                        gdp_gin_t *gin,
813 4217d271 Eric Allman
                        uint32_t n_hashes,
814
                        gdp_hash_t **hashes,
815 d65c01e2 Eric Allman
                        gdp_event_cbfunc_t cbfunc,
816
                        void *cbarg)
817
{
818
        return GDP_STAT_NOT_IMPLEMENTED;
819
}
820
821
822 eae1d3ec Eric Allman
#if 0
823 d65c01e2 Eric Allman
// back compat
824
EP_STAT
825
gdp_gcl_read_async(
826 eae1d3ec Eric Allman
                        gdp_gin_t *gin,
827 d65c01e2 Eric Allman
                        gdp_recno_t recno,
828 eae1d3ec Eric Allman
                        int32_t nrecs,
829 d65c01e2 Eric Allman
                        gdp_event_cbfunc_t cbfunc,
830
                        void *cbarg)
831
{
832 eae1d3ec Eric Allman
        return gdp_gcl_read_by_recno_async(gin, recno, nrecs, cbfunc, cbarg);
833 d65c01e2 Eric Allman
}
834 eae1d3ec Eric Allman
#endif
835 d65c01e2 Eric Allman
836
837
838 8204d4b2 Eric Allman
839
/*
840 eae1d3ec Eric Allman
**        GDP_GIN_SUBSCRIBE_BY_RECNO --- subscribe starting from a record number
841 cd2ef2a6 Eric Allman
*/
842
843
EP_STAT
844 eae1d3ec Eric Allman
gdp_gin_subscribe_by_recno(gdp_gin_t *gin,
845 9509f13b Eric Allman
                gdp_recno_t start,
846 2e4a5d7d Eric Allman
                int32_t numrecs,
847 10125206 Eric Allman
                gdp_sub_qos_t *qos,
848 728e4394 Eric Allman
                gdp_event_cbfunc_t cbfunc,
849 cd2ef2a6 Eric Allman
                void *cbarg)
850
{
851 d2647d1f Eric Allman
        EP_STAT estat;
852
853 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_subscribe_by_recno\n");
854
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_subscribe_by_recno");
855 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
856 6dfc87d5 Eric Allman
857 eae1d3ec Eric Allman
        estat = _gdp_gin_subscribe(gin, GDP_CMD_SUBSCRIBE_BY_RECNO, start, numrecs,
858 10125206 Eric Allman
                                                        qos, cbfunc, cbarg);
859 d2647d1f Eric Allman
860 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_subscribe_by_recno");
861
        prstat(estat, gin, "gdp_gin_subscribe_by_recno");
862 d2647d1f Eric Allman
        return estat;
863 328d0948 Eric Allman
}
864
865
866
/*
867 eae1d3ec Eric Allman
**        GDP_GIN_SUBSCRIBE_BY_TS --- subscribe to a GOB starting from a timestamp
868 d2647d1f Eric Allman
*/
869
870
EP_STAT
871 eae1d3ec Eric Allman
gdp_gin_subscribe_by_ts(gdp_gin_t *gin,
872 d2647d1f Eric Allman
                EP_TIME_SPEC *start,
873
                int32_t numrecs,
874 10125206 Eric Allman
                gdp_sub_qos_t *qos,
875 d2647d1f Eric Allman
                gdp_event_cbfunc_t cbfunc,
876
                void *cbarg)
877
{
878
        EP_STAT estat;
879
880 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_subscribe_by_ts\n");
881 d65c01e2 Eric Allman
#if 0 //TODO
882 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_subscribe_by_ts");
883 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
884 6dfc87d5 Eric Allman

885 d2647d1f Eric Allman
        // create the subscribe request
886 d65c01e2 Eric Allman
        gdp_req_t *req;
887
        estat = _gdp_req_new(GDP_CMD_SUBSCRIBE_BY_TS, gin->gob, _GdpChannel, NULL,
888 d2647d1f Eric Allman
                        GDP_REQ_PERSIST | GDP_REQ_CLT_SUBSCR | GDP_REQ_ALLOC_RID,
889
                        &req);
890
        EP_STAT_CHECK(estat, goto fail0);
891

892
        // add start and stop parameters to PDU
893 fec93aac Eric Allman
        req->gin = gin;
894 d65c01e2 Eric Allman
        memcpy(&req->cpdu->m->b->datum->d->ts, start, sizeof req->cpdu->m->b->datum->d->ts);
895 d2647d1f Eric Allman
        req->numrecs = numrecs;
896

897
        // now do the hard work
898 eae1d3ec Eric Allman
        estat = _gdp_gin_subscribe(req, numrecs, timeout, cbfunc, cbarg);
899 d2647d1f Eric Allman
fail0:
900 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_subscribe_by_ts");
901 d65c01e2 Eric Allman
#else        //TODO
902
        estat = GDP_STAT_NOT_IMPLEMENTED;
903
#endif        //TODO
904 eae1d3ec Eric Allman
        prstat(estat, gin, "gdp_gin_subscribe_by_ts");
905 d2647d1f Eric Allman
        return estat;
906
}
907
908
909
/*
910 eae1d3ec Eric Allman
**  GDP_GIN_UNSUBSCRIBE --- delete subscriptions to a named GOB
911 9c515e64 Eric Allman
*/
912
913
EP_STAT
914 eae1d3ec Eric Allman
gdp_gin_unsubscribe(gdp_gin_t *gin,
915 9c515e64 Eric Allman
                gdp_event_cbfunc_t cbfunc,
916
                void *cbarg)
917
{
918
        EP_STAT estat;
919
920 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_unsubscribe\n");
921 9c515e64 Eric Allman
922 eae1d3ec Eric Allman
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_unsubscribe");
923 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
924 eae1d3ec Eric Allman
        estat = _gdp_gin_unsubscribe(gin, cbfunc, cbarg, 0);
925
        unlock_gin_and_gob(gin, "gdp_gin_unsubscribe");
926 9c515e64 Eric Allman
927 eae1d3ec Eric Allman
        prstat(estat, gin, "gdp_gin_unsubscribe");
928 9c515e64 Eric Allman
        return estat;
929
}
930
931
932 932f745e Eric Allman
/*
933 eae1d3ec Eric Allman
**  GDP_GIN_GETMETADATA --- return the metadata associated with a GOB
934 932f745e Eric Allman
*/
935
936 158a49ba Eric Allman
EP_STAT
937 eae1d3ec Eric Allman
gdp_gin_getmetadata(gdp_gin_t *gin,
938
                gdp_md_t **gmdp)
939 158a49ba Eric Allman
{
940 8701c522 Eric Allman
        EP_STAT estat;
941
942 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_getmetadata\n");
943
        estat = check_and_lock_gin_and_gob(gin, "gdp_gin_getmetadata");
944 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
945
        estat = _gdp_gob_getmetadata(gin->gob, gmdp, _GdpChannel, 0);
946 eae1d3ec Eric Allman
        unlock_gin_and_gob(gin, "gdp_gin_getmetadata");
947
        prstat(estat, gin, "gdp_gin_getmetadata");
948 8701c522 Eric Allman
        return estat;
949 158a49ba Eric Allman
}
950 34612550 Eric Allman
951
952 f9b45862 Eric Allman
/*
953 eae1d3ec Eric Allman
**  GDP_GIN_SET_APPEND_FILTER --- set the append filter function
954 34612550 Eric Allman
*/
955
956 1ca7751e Eric Allman
EP_STAT
957 eae1d3ec Eric Allman
gdp_gin_set_append_filter(gdp_gin_t *gin,
958 34612550 Eric Allman
                EP_STAT (*appendfilter)(gdp_datum_t *, void *),
959
                void *filterdata)
960
{
961 fec93aac Eric Allman
        EP_STAT estat;
962
963 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_set_append_filter\n");
964
        estat = check_and_lock_gin(gin, "gdp_gin_set_append_filter");
965 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
966
        gin->apndfilter = appendfilter;
967
        gin->apndfpriv = filterdata;
968
        _gdp_gin_unlock(gin);
969 1ca7751e Eric Allman
        return EP_STAT_OK;
970 34612550 Eric Allman
}
971
972
973
/*
974 eae1d3ec Eric Allman
**  GDP_GIN_SET_READ_FILTER --- set the read filter function
975 34612550 Eric Allman
*/
976
977 1ca7751e Eric Allman
EP_STAT
978 eae1d3ec Eric Allman
gdp_gin_set_read_filter(gdp_gin_t *gin,
979 34612550 Eric Allman
                EP_STAT (*readfilter)(gdp_datum_t *, void *),
980
                void *filterdata)
981
{
982 fec93aac Eric Allman
        EP_STAT estat;
983
984 eae1d3ec Eric Allman
        ep_dbg_cprintf(Dbg, 39, "\n>>> gdp_gin_set_read_filter\n");
985
        estat = check_and_lock_gin(gin, "gdp_gin_set_read_filter");
986 fec93aac Eric Allman
        EP_STAT_CHECK(estat, return estat);
987
        gin->readfilter = readfilter;
988
        gin->readfpriv = filterdata;
989
        _gdp_gin_unlock(gin);
990 1ca7751e Eric Allman
        return EP_STAT_OK;
991 34612550 Eric Allman
}
992 7d83fa37 Eric Allman
993
994
/*
995 eae1d3ec Eric Allman
**  GDP Open Information handling
996 7d83fa37 Eric Allman
*/
997
998 eae1d3ec Eric Allman
gdp_open_info_t *
999
gdp_open_info_new(void)
1000 7d83fa37 Eric Allman
{
1001 eae1d3ec Eric Allman
        gdp_open_info_t *info;
1002 7d83fa37 Eric Allman
1003 eae1d3ec Eric Allman
        info = (gdp_open_info_t *) ep_mem_zalloc(sizeof*info);
1004 7d83fa37 Eric Allman
        return info;
1005
}
1006
1007
void
1008 eae1d3ec Eric Allman
gdp_open_info_free(gdp_open_info_t *info)
1009 7d83fa37 Eric Allman
{
1010 ddb857b7 Eric Allman
        //XXX should check for info == NULL here
1011 7d83fa37 Eric Allman
        if (info->signkey != NULL)
1012
                ep_crypto_key_free(info->signkey);
1013
        ep_mem_free(info);
1014
}
1015
1016
EP_STAT
1017 eae1d3ec Eric Allman
gdp_open_info_set_signing_key(gdp_open_info_t *info,
1018 7d83fa37 Eric Allman
                EP_CRYPTO_KEY *skey)
1019
{
1020 ddb857b7 Eric Allman
        //XXX should check for info == NULL here
1021 7d83fa37 Eric Allman
        info->signkey = skey;
1022
        return EP_STAT_OK;
1023
}
1024 ee6b5440 Eric Allman
1025
EP_STAT
1026 eae1d3ec Eric Allman
gdp_open_info_set_signkey_cb(
1027
                                gdp_open_info_t *info,
1028 284a8bac Eric Allman
                                EP_STAT (*signkey_cb)(
1029
                                        gdp_name_t gname,
1030
                                        void *signkey_udata,
1031
                                        EP_CRYPTO_KEY **skey),
1032
                                void *signkey_udata)
1033
{
1034 ddb857b7 Eric Allman
        //XXX should check for info == NULL here
1035 284a8bac Eric Allman
        info->signkey_cb = signkey_cb;
1036
        info->signkey_udata = signkey_udata;
1037
        return EP_STAT_OK;
1038
}
1039
1040
EP_STAT
1041 eae1d3ec Eric Allman
gdp_open_info_set_caching(
1042
                gdp_open_info_t *info,
1043 ee6b5440 Eric Allman
                bool keep_in_cache)
1044
{
1045 ddb857b7 Eric Allman
        //XXX should check for info == NULL here
1046 c9f4745b Eric Allman
        if (keep_in_cache)
1047
                info->flags |= GOIF_KEEP_IN_CACHE;
1048
        else
1049
                info->flags &= ~GOIF_KEEP_IN_CACHE;
1050
        return EP_STAT_OK;
1051
}
1052
1053
EP_STAT
1054
gdp_open_info_set_vrfy(
1055
                gdp_open_info_t *info,
1056
                bool verify_proof)
1057
{
1058
        //XXX should check for info == NULL here
1059
        //XXX ideally this would check to make sure we have a public key,
1060
        //XXX        but that isn't possible yet.
1061
        if (verify_proof)
1062
                info->flags |= GOIF_VERIFY_PROOF;
1063
        else
1064
                info->flags &= ~GOIF_VERIFY_PROOF;
1065 ee6b5440 Eric Allman
        return EP_STAT_OK;
1066
}
1067 49d76189 Eric Allman
1068
EP_STAT
1069
gdp_open_info_set_no_skey_nonfatal(
1070
                gdp_open_info_t *info,
1071
                bool nonfatal)
1072
{
1073
        if (nonfatal)
1074
                info->flags |= GOIF_NO_SKEY_NONFATAL;
1075
        else
1076
                info->flags &= ~GOIF_NO_SKEY_NONFATAL;
1077
        return EP_STAT_OK;
1078
}