3 * Key attribute manipulation
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28 /*----- Header files ------------------------------------------------------*/
36 #include <mLib/dstr.h>
37 #include <mLib/macros.h>
42 /*----- Main code ---------------------------------------------------------*/
44 /* --- @key_chkident@ --- *
46 * Arguments: @const char *p@ = pointer to a type string
48 * Returns: Zero if OK, -1 on error.
50 * Use: Checks whether an identification component string is OK.
53 int key_chkident(const char *p)
55 if (!p || !*p || strlen(p) > 255)
58 if (*p == ':' || *p == '.' || ISSPACE(*p))
65 /* --- @key_chkcomment@ --- *
67 * Arguments: @const char *p@ = pointer to a comment string
69 * Returns: Zero if OK, -1 on error.
71 * Use: Checks whether a comment string is OK.
74 int key_chkcomment(const char *p)
88 /* --- @key_mkattriter@ --- *
90 * Arguments: @key_attriter *i@ = pointer to attribute iterator
91 * @key *k@ = pointer to key
95 * Use: Initializes an attribute iterator. The attributes are
96 * returned by @key_nextattr@.
99 void key_mkattriter(key_attriter *i, key *k)
101 sym_mkiter(&i->i, &k->a);
104 /* --- @key_nextattr@ --- *
106 * Arguments: @key_attriter *i@ = pointer to attribute iterator
107 * @const char **n, **v@ = pointers to name and value
109 * Returns: Zero if no attribute available, or nonzero if returned OK.
111 * Use: Returns the next attribute.
114 int key_nextattr(key_attriter *i, const char **n, const char **v)
116 key_attr *a = sym_next(&i->i);
119 if (n) *n = SYM_NAME(a);
124 /* --- @key_getattr@ --- *
126 * Arguments: @key_file *f@ = pointer to file
127 * @key *k@ = pointer to key
128 * @const char *n@ = pointer to attribute name
130 * Returns: Pointer to attribute value, or null if not found.
132 * Use: Returns the value of a key attribute.
135 const char *key_getattr(key_file *f, key *k, const char *n)
138 if ((a = sym_find(&k->a, n, -1, 0, 0)) == 0)
143 /* --- @key_putattr@ --- *
145 * Arguments: @key_file *f@ = pointer to file
146 * @key *k@ = pointer to key
147 * @const char *n@ = pointer to attribute name
148 * @const char *v@ = pointer to attribute value or null
150 * Returns: Error code (one of the @KERR@ constants).
152 * Use: Inserts an attribute on a key. If an attribute with the same
153 * name already exists, it is deleted. Setting a null value
154 * removes the attribute.
157 int key_putattr(key_file *f, key *k, const char *n, const char *v)
162 if (!(f->f & KF_WRITE))
163 return (KERR_READONLY);
165 return (KERR_BADATTR);
168 a = sym_find(&k->a, n, -1, sizeof(*a), &found);
172 } else if ((a = sym_find(&k->a, n, -1, 0, 0)) != 0) {
174 sym_remove(&k->a, a);
181 /* --- @key_setkeydata@ --- *
183 * Arguments: @key_file *kf@ = pointer to key file
184 * @key *k@ = pointer to key
185 * @key_data *kd@ = new key data
187 * Returns: Zero on success, or a @KERR_@ error code on failure.
189 * Use: Sets the key data for a key.
192 int key_setkeydata(key_file *kf, key *k, key_data *kd)
194 if (!(kf->f & KF_WRITE))
195 return (KERR_READONLY);
199 kf->f |= KF_MODIFIED;
203 /* --- @key_setcomment@ --- *
205 * Arguments: @key_file *f@ = pointer to key file block
206 * @key *k@ = pointer to key block
207 * @const char *c@ = pointer to comment to set, or zero
209 * Returns: Error code (one of the @KERR@ constants).
211 * Use: Replaces the key's current comment with a new one.
214 int key_setcomment(key_file *f, key *k, const char *c)
216 if (!(f->f & KF_WRITE))
217 return (KERR_READONLY);
218 if (key_chkcomment(c))
219 return (KERR_BADCOMMENT);
230 /* --- @key_settag@ --- *
232 * Arguments: @key_file *f@ = pointer to key file block
233 * @key *k@ = pointer to key block
234 * @const char *tag@ = pointer to comment to set, or zero
236 * Returns: Error code (one of the @KERR@ constants).
238 * Use: Replaces the key's current tag with a new one.
241 int key_settag(key_file *f, key *k, const char *tag)
246 if (!(f->f & KF_WRITE))
247 return (KERR_READONLY);
249 /* --- Make sure the tag is OK --- */
251 if (tag && key_chkident(tag))
252 return (KERR_BADTAG);
254 /* --- See if the new tag is the same as the old one --- */
256 if ((!tag && !k->tag) || (tag && k->tag && STRCMP(tag, ==, k->tag)))
259 /* --- Allocate an entry for the new tag --- */
262 kr = sym_find(&f->bytag, tag, -1, sizeof(*kr), &found);
263 if (found && !KEY_EXPIRED(time(0), kr->k->del))
264 return (KERR_DUPTAG);
268 /* --- Remove any existing tag --- */
271 kr = sym_find(&f->bytag, k->tag, -1, 0, 0);
272 assert(((void)"No bytag link", kr));
273 sym_remove(&f->bytag, kr);
281 k->tag = xstrdup(tag);
287 /* --- @key_fulltag@ --- *
289 * Arguments: @key *k@ = pointer to key
290 * @dstr *d@ = pointer to destination string
294 * Use: Emits the key's full tag, which has the form
295 * `ID:TYPE[:TAG]'. This is used in the textual file format,
296 * and to identify passphrases for locked keys.
299 void key_fulltag(key *k, dstr *d)
301 dstr_putf(d, "%08lx:%s", (unsigned long)k->id, k->type);
303 dstr_putf(d, ":%s", k->tag);
306 /*----- That's all, folks -------------------------------------------------*/