Hash utilities: maintain a hash state object, not a bundle of arguments.
[u/mdw/catacomb] / key-flags.c
CommitLineData
d11a0bf7 1/* -*-c-*-
2 *
3384672a 3 * $Id$
d11a0bf7 4 *
5 * Reading and writing key flag strings
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
45c0fd36 10/*----- Licensing notice --------------------------------------------------*
d11a0bf7 11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
45c0fd36 18 *
d11a0bf7 19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
45c0fd36 23 *
d11a0bf7 24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
d11a0bf7 30/*----- Header files ------------------------------------------------------*/
31
32#include <stdlib.h>
33#include <string.h>
34
35#include <mLib/bits.h>
36#include <mLib/dstr.h>
37
38#include "key.h"
39
40/*----- Data structures ---------------------------------------------------*/
41
42typedef struct key_flags {
43 unsigned f;
44 unsigned m;
45} key_flags;
46
47/*----- Flags table -------------------------------------------------------*/
48
49typedef struct flagent {
50 const char *name;
51 unsigned f;
52 unsigned m;
53} flagent;
54
4e66da02 55static const flagent flagtab[] = {
d11a0bf7 56
57 /* --- Encoding types --- */
58
59 { "binary", KENC_BINARY, KF_ENCMASK },
60 { "integer", KENC_MP, KF_ENCMASK },
61 { "struct", KENC_STRUCT, KF_ENCMASK },
62 { "encrypt", KENC_ENCRYPT, KF_ENCMASK },
1ba83484 63 { "string", KENC_STRING, KF_ENCMASK },
64 { "ec", KENC_EC, KF_ENCMASK },
d11a0bf7 65
66 /* --- Classes of keys --- */
67
68 { "shared", KCAT_SHARE, KF_CATMASK },
69 { "public", KCAT_PUB, KF_CATMASK },
70 { "private", KCAT_PRIV, KF_CATMASK },
71 { "symmetric", KCAT_SYMM, KF_CATMASK },
72 { "secret", 0, KF_NONSECRET },
73 { "-secret", KF_NONSECRET, KF_NONSECRET },
74
75 /* --- Other flags --- */
76
77 { "burn", KF_BURN, KF_BURN },
78 { "-burn", 0, KF_BURN },
79
80 /* --- End marker --- */
81
82 { 0, 0, 0 }
83};
84
85/*----- Main code ---------------------------------------------------------*/
86
87/* --- @key_readflags@ --- *
88 *
89 * Arguments: @const char *p@ = pointer to string to read
90 * @char **pp@ = where to store the end pointer
91 * @unsigned *ff@ = where to store the flags
92 * @unsigned *mm@ = where to store the mask
93 *
94 * Returns: Zero if all went well, nonzero if there was an error.
95 *
96 * Use: Reads a flag string.
97 */
98
99int key_readflags(const char *p, char **pp, unsigned *ff, unsigned *mm)
100{
101 unsigned f = 0, m = 0;
102
103 for (;;) {
104 size_t sz = strcspn(p, ",:");
4e66da02 105 const flagent *e, *ee = 0;
d11a0bf7 106
107 /* --- Look up the string in the flags table --- */
108
b817bfc6 109 if (sz == 4 && strncmp(p, "none", 4) == 0)
110 goto next;
d11a0bf7 111 for (e = flagtab; e->name; e++) {
112 if (strncmp(e->name, p, sz) == 0) {
113 if (e->name[sz] == 0) {
114 ee = e;
115 break;
116 } else if (ee)
117 return (KERR_BADFLAGS);
118 else
119 ee = e;
120 }
121 }
122 if (!ee)
123 return (KERR_BADFLAGS);
124
125 /* --- Adjust the flag words --- *
126 *
127 * Ensure that the flags set are disjoint.
128 */
129
130 if (m & ee->m)
131 return (KERR_BADFLAGS);
132 m |= ee->m;
133 f |= ee->f;
b817bfc6 134 next:
d11a0bf7 135 p += sz;
136 if (*p == 0 || *p == ':')
137 break;
138 p++;
139 }
140
141 /* --- Report the results --- */
142
143 if (ff) *ff = f;
144 if (mm) *mm = m;
145 if (pp) *pp = (char *)p;
146 return (0);
147}
148
149/* --- @key_writeflags@ --- *
150 *
151 * Arguments: @unsigned f@ = flags to write
152 * @dstr *d@ = pointer to destination string
153 *
154 * Returns: ---
155 *
156 * Use: Emits a flags word as a string representation.
157 */
158
159void key_writeflags(unsigned f, dstr *d)
160{
161 int del = 0;
4e66da02 162 const flagent *e;
d11a0bf7 163 unsigned m = 0;
164
165 for (e = flagtab; e->name; e++) {
166 if (m & e->m || e->name[0] == '-' || (f & e->m) != e->f)
167 continue;
168 if (del)
169 DPUTC(d, ',');
170 DPUTS(d, e->name);
171 m |= e->m;
172 del = 1;
173 }
174}
175
052b36d0 176/* --- @key_match@ --- *
177 *
178 * Arguments: @key_data *k@ = pointer to key data block
179 * @const key_filter *kf@ = pointer to filter block
180 *
181 * Returns: Nonzero if the key matches the filter.
182 *
183 * Use: Checks whether a key matches a filter.
184 */
185
186int key_match(key_data *k, const key_filter *kf)
187{
3384672a 188 key_subkeyiter i;
189 const char *tag;
190 key_data *kd;
052b36d0 191
192 if (!kf)
193 return (1);
194 if ((k->e & KF_ENCMASK) != KENC_STRUCT)
195 return ((k->e & kf->m) == kf->f);
196
3384672a 197 for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) {
198 if (key_match(kd, kf))
052b36d0 199 return (1);
200 }
201 return (0);
202}
203
d11a0bf7 204/*----- That's all, folks -------------------------------------------------*/