]> git.stg.codes - stg.git/blob - libs/smux/constraints.c
Merge remote-tracking branch 'github/master'
[stg.git] / libs / smux / constraints.c
1 #include <asn_internal.h>
2 #include <constraints.h>
3
4 int
5 asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor,
6                           const void *struct_ptr,
7                           asn_app_constraint_failed_f *cb, void *key) {
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(const asn_TYPE_descriptor_t *type_descriptor,
19                                const void *struct_ptr,
20                                asn_app_constraint_failed_f *cb, void *key) {
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     const 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, const asn_TYPE_descriptor_t *td, const void *sptr,
39                 const char *fmt, ...) {
40     struct errbufDesc *arg = key;
41         va_list ap;
42         ssize_t vlen;
43         ssize_t maxlen;
44
45         arg->failed_type = td;
46         arg->failed_struct_ptr = sptr;
47
48         maxlen = arg->errlen;
49         if(maxlen <= 0)
50                 return;
51
52         va_start(ap, fmt);
53         vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
54         va_end(ap);
55         if(vlen >= maxlen) {
56                 arg->errbuf[maxlen-1] = '\0';   /* Ensuring libc correctness */
57                 arg->errlen = maxlen - 1;       /* Not counting termination */
58                 return;
59         } else if(vlen >= 0) {
60                 arg->errbuf[vlen] = '\0';       /* Ensuring libc correctness */
61                 arg->errlen = vlen;             /* Not counting termination */
62         } else {
63                 /*
64                  * The libc on this system is broken.
65                  */
66                 vlen = sizeof("<broken vsnprintf>") - 1;
67                 maxlen--;
68                 arg->errlen = vlen < maxlen ? vlen : maxlen;
69                 memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
70                 arg->errbuf[arg->errlen] = 0;
71         }
72
73         return;
74 }
75
76 int
77 asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor,
78                       const void *struct_ptr, char *errbuf, size_t *errlen) {
79     struct errbufDesc arg;
80     int ret;
81
82     arg.failed_type = 0;
83     arg.failed_struct_ptr = 0;
84     arg.errbuf = errbuf;
85     arg.errlen = errlen ? *errlen : 0;
86
87     ret = type_descriptor->encoding_constraints.general_constraints(
88         type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg);
89     if(ret == -1 && errlen) *errlen = arg.errlen;
90
91     return ret;
92 }
93