Only produce initialization message if verbose.
[u/mdw/catacomb] / key-attr.c
CommitLineData
d11a0bf7 1/* -*-c-*-
2 *
3 * $Id: key-attr.c,v 1.1 1999/12/22 15:47:48 mdw Exp $
4 *
5 * Key attribute manipulation
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
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.
18 *
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.
23 *
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
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: key-attr.c,v $
33 * Revision 1.1 1999/12/22 15:47:48 mdw
34 * Major key-management revision.
35 *
36 */
37
38/*----- Header files ------------------------------------------------------*/
39
40#include <ctype.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <time.h>
45
46#include <mLib/alloc.h>
47#include <mLib/sym.h>
48
49#include "key.h"
50
51/*----- Main code ---------------------------------------------------------*/
52
53/* --- @key_chkident@ --- *
54 *
55 * Arguments: @const char *p@ = pointer to a type string
56 *
57 * Returns: Zero if OK, -1 on error.
58 *
59 * Use: Checks whether an identification component string is OK.
60 */
61
62int key_chkident(const char *p)
63{
64 if (!p || !*p)
65 return (-1);
66 while (*p) {
67 if (*p == ':' || *p == '.' || isspace((unsigned char)*p))
68 return (-1);
69 p++;
70 }
71 return (0);
72}
73
74/* --- @key_chkcomment@ --- *
75 *
76 * Arguments: @const char *p@ = pointer to a comment string
77 *
78 * Returns: Zero if OK, -1 on error.
79 *
80 * Use: Checks whether a comment string is OK.
81 */
82
83int key_chkcomment(const char *p)
84{
85 if (!p)
86 return (0);
87 if (!*p)
88 return (-1);
89 while (*p) {
90 if (*p == '\n')
91 return (-1);
92 p++;
93 }
94 return (0);
95}
96
97/* --- @key_mkattriter@ --- *
98 *
99 * Arguments: @key_attriter *i@ = pointer to attribute iterator
100 * @key *k@ = pointer to key
101 *
102 * Returns: ---
103 *
104 * Use: Initializes an attribute iterator. The attributes are
105 * returned by @key_nextattr@.
106 */
107
108void key_mkattriter(key_attriter *i, key *k)
109{
110 sym_mkiter(&i->i, &k->a);
111}
112
113/* --- @key_nextattr@ --- *
114 *
115 * Arguments: @key_attriter *i@ = pointer to attribute iterator
116 * @const char **n, **v@ = pointers to name and value
117 *
118 * Returns: Zero if no attribute available, or nonzero if returned OK.
119 *
120 * Use: Returns the next attribute.
121 */
122
123int key_nextattr(key_attriter *i, const char **n, const char **v)
124{
125 key_attr *a = sym_next(&i->i);
126 if (!a)
127 return (0);
128 *n = SYM_NAME(a);
129 *v = a->p;
130 return (1);
131}
132
133/* --- @key_getattr@ --- *
134 *
135 * Arguments: @key_file *f@ = pointer to file
136 * @key *k@ = pointer to key
137 * @const char *n@ = pointer to attribute name
138 *
139 * Returns: Pointer to attribute value, or null if not found.
140 *
141 * Use: Returns the value of a key attribute.
142 */
143
144const char *key_getattr(key_file *f, key *k, const char *n)
145{
146 key_attr *a;
147 if ((a = sym_find(&k->a, n, -1, 0, 0)) == 0)
148 return (0);
149 return (a->p);
150}
151
152/* --- @key_putattr@ --- *
153 *
154 * Arguments: @key_file *f@ = pointer to file
155 * @key *k@ = pointer to key
156 * @const char *n@ = pointer to attribute name
157 * @const char *v@ = pointer to attribute value or null
158 *
159 * Returns: Error code (one of the @KERR@ constants).
160 *
161 * Use: Inserts an attribute on a key. If an attribute with the same
162 * name already exists, it is deleted. Setting a null value
163 * removes the attribute.
164 */
165
166int key_putattr(key_file *f, key *k, const char *n, const char *v)
167{
168 key_attr *a;
169 unsigned found;
170
171 if (!(f->f & KF_WRITE))
172 return (KERR_READONLY);
173
174 if (v) {
175 a = sym_find(&k->a, n, -1, sizeof(*a), &found);
176 if (found)
177 free(a->p);
178 a->p = xstrdup(v);
179 } else if ((a = sym_find(&k->a, n, -1, 0, 0)) != 0) {
180 free(a->p);
181 sym_remove(&k->a, a);
182 }
183
184 f->f |= KF_MODIFIED;
185 return (0);
186}
187
188/* --- @key_setcomment@ --- *
189 *
190 * Arguments: @key_file *f@ = pointer to key file block
191 * @key *k@ = pointer to key block
192 * @const char *c@ = pointer to comment to set, or zero
193 *
194 * Returns: Error code (one of the @KERR@ constants).
195 *
196 * Use: Replaces the key's current comment with a new one.
197 */
198
199int key_setcomment(key_file *f, key *k, const char *c)
200{
201 if (!(f->f & KF_WRITE))
202 return (KERR_READONLY);
203 if (key_chkcomment(c))
204 return (KERR_BADCOMMENT);
205 if (k->c)
206 free(k->c);
207 if (c)
208 k->c = xstrdup(c);
209 else
210 k->c = 0;
211 f->f |= KF_MODIFIED;
212 return (0);
213}
214
215/* --- @key_settag@ --- *
216 *
217 * Arguments: @key_file *f@ = pointer to key file block
218 * @key *k@ = pointer to key block
219 * @const char *tag@ = pointer to comment to set, or zero
220 *
221 * Returns: Error code (one of the @KERR@ constants).
222 *
223 * Use: Replaces the key's current tag with a new one.
224 */
225
226int key_settag(key_file *f, key *k, const char *tag)
227{
228 key_ref *kr;
229 unsigned found;
230
231 if (!(f->f & KF_WRITE))
232 return (KERR_READONLY);
233
234 /* --- Make sure the tag is OK --- */
235
236 if (tag && key_chkident(tag))
237 return (KERR_BADTAG);
238
239 /* --- See if the new tag is the same as the old one --- */
240
241 if ((!tag && !k->tag) ||
242 (tag && k->tag && strcmp(tag, k->tag) == 0))
243 return (0);
244
245 /* --- Allocate an entry for the new tag --- */
246
247 if (tag) {
248 kr = sym_find(&f->bytag, tag, -1, sizeof(*kr), &found);
249 if (found)
250 return (KERR_DUPTAG);
251 kr->k = k;
252 }
253
254 /* --- Remove any existing tag --- */
255
256 if (k->tag) {
257 kr = sym_find(&f->bytag, k->tag, -1, 0, 0);
258 assert(((void)"No bytag link", kr));
259 sym_remove(&f->bytag, kr);
260 free(k->tag);
261 }
262
263 /* --- Done --- */
264
265 f->f |= KF_MODIFIED;
266 if (tag)
267 k->tag = xstrdup(tag);
268 else
269 k->tag = 0;
270 return (0);
271}
272
273/* --- @key_fulltag@ --- *
274 *
275 * Arguments: @key *k@ = pointer to key
276 * @dstr *d@ = pointer to destination string
277 *
278 * Returns: ---
279 *
280 * Use: Emits the key's full tag, which has the form
281 * `ID:TYPE[:TAG]'. This is used in the textual file format,
282 * and to identify passphrases for locked keys.
283 */
284
285void key_fulltag(key *k, dstr *d)
286{
287 dstr_putf(d, "%08lx:%s", (unsigned long)k->id, k->type);
288 if (k->tag)
289 dstr_putf(d, ":%s", k->tag);
290}
291
292/*----- That's all, folks -------------------------------------------------*/