]> git.stg.codes - stg.git/blob - libs/smux/constraints.c
Non-virtual admin.
[stg.git] / libs / smux / constraints.c
1 #include "asn_internal.h"
2 #include "constraints.h"
3
4 int
5 asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor,
6         const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
7
8         (void)type_descriptor;  /* Unused argument */
9         (void)struct_ptr;       /* Unused argument */
10         (void)cb;       /* Unused argument */
11         (void)key;      /* Unused argument */
12
13         /* Nothing to check */
14         return 0;
15 }
16
17 int
18 asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor,
19         const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
20
21         (void)type_descriptor;  /* Unused argument */
22         (void)struct_ptr;       /* Unused argument */
23         (void)cb;       /* Unused argument */
24         (void)key;      /* Unused argument */
25
26         /* Unknown how to check */
27         return 0;
28 }
29
30 struct errbufDesc {
31         asn_TYPE_descriptor_t *failed_type;
32         const void *failed_struct_ptr;
33         char *errbuf;
34         size_t errlen;
35 };
36
37 static void
38 _asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) {
39         struct errbufDesc *arg = key;
40         va_list ap;
41         ssize_t vlen;
42         ssize_t maxlen;
43
44         arg->failed_type = td;
45         arg->failed_struct_ptr = sptr;
46
47         maxlen = arg->errlen;
48         if(maxlen <= 0)
49                 return;
50
51         va_start(ap, fmt);
52         vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
53         va_end(ap);
54         if(vlen >= maxlen) {
55                 arg->errbuf[maxlen-1] = '\0';   /* Ensuring libc correctness */
56                 arg->errlen = maxlen - 1;       /* Not counting termination */
57                 return;
58         } else if(vlen >= 0) {
59                 arg->errbuf[vlen] = '\0';       /* Ensuring libc correctness */
60                 arg->errlen = vlen;             /* Not counting termination */
61         } else {
62                 /*
63                  * The libc on this system is broken.
64                  */
65                 vlen = sizeof("<broken vsnprintf>") - 1;
66                 maxlen--;
67                 arg->errlen = vlen < maxlen ? vlen : maxlen;
68                 memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
69                 arg->errbuf[arg->errlen] = 0;
70         }
71
72         return;
73 }
74
75 int
76 asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor,
77                 const void *struct_ptr, char *errbuf, size_t *errlen) {
78         struct errbufDesc arg;
79         int ret;
80
81         arg.failed_type = 0;
82         arg.failed_struct_ptr = 0;
83         arg.errbuf = errbuf;
84         arg.errlen = errlen ? *errlen : 0;
85
86         ret = type_descriptor->check_constraints(type_descriptor,
87                 struct_ptr, _asn_i_ctfailcb, &arg);
88         if(ret == -1 && errlen)
89                 *errlen = arg.errlen;
90
91         return ret;
92 }
93