3 * $Id: key-attr.c,v 1.3 2001/06/22 19:39:43 mdw Exp $
5 * Key attribute manipulation
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
32 * $Log: key-attr.c,v $
33 * Revision 1.3 2001/06/22 19:39:43 mdw
34 * Allow tagging if the tag is owned by a deleted key.
36 * Revision 1.2 2000/02/12 18:21:02 mdw
37 * Overhaul of key management (again).
39 * Revision 1.1 1999/12/22 15:47:48 mdw
40 * Major key-management revision.
44 /*----- Header files ------------------------------------------------------*/
52 #include <mLib/dstr.h>
57 /*----- Main code ---------------------------------------------------------*/
59 /* --- @key_chkident@ --- *
61 * Arguments: @const char *p@ = pointer to a type string
63 * Returns: Zero if OK, -1 on error.
65 * Use: Checks whether an identification component string is OK.
68 int key_chkident(const char *p
)
73 if (*p
== ':' || *p
== '.' || isspace((unsigned char)*p
))
80 /* --- @key_chkcomment@ --- *
82 * Arguments: @const char *p@ = pointer to a comment string
84 * Returns: Zero if OK, -1 on error.
86 * Use: Checks whether a comment string is OK.
89 int key_chkcomment(const char *p
)
103 /* --- @key_mkattriter@ --- *
105 * Arguments: @key_attriter *i@ = pointer to attribute iterator
106 * @key *k@ = pointer to key
110 * Use: Initializes an attribute iterator. The attributes are
111 * returned by @key_nextattr@.
114 void key_mkattriter(key_attriter
*i
, key
*k
)
116 sym_mkiter(&i
->i
, &k
->a
);
119 /* --- @key_nextattr@ --- *
121 * Arguments: @key_attriter *i@ = pointer to attribute iterator
122 * @const char **n, **v@ = pointers to name and value
124 * Returns: Zero if no attribute available, or nonzero if returned OK.
126 * Use: Returns the next attribute.
129 int key_nextattr(key_attriter
*i
, const char **n
, const char **v
)
131 key_attr
*a
= sym_next(&i
->i
);
139 /* --- @key_getattr@ --- *
141 * Arguments: @key_file *f@ = pointer to file
142 * @key *k@ = pointer to key
143 * @const char *n@ = pointer to attribute name
145 * Returns: Pointer to attribute value, or null if not found.
147 * Use: Returns the value of a key attribute.
150 const char *key_getattr(key_file
*f
, key
*k
, const char *n
)
153 if ((a
= sym_find(&k
->a
, n
, -1, 0, 0)) == 0)
158 /* --- @key_putattr@ --- *
160 * Arguments: @key_file *f@ = pointer to file
161 * @key *k@ = pointer to key
162 * @const char *n@ = pointer to attribute name
163 * @const char *v@ = pointer to attribute value or null
165 * Returns: Error code (one of the @KERR@ constants).
167 * Use: Inserts an attribute on a key. If an attribute with the same
168 * name already exists, it is deleted. Setting a null value
169 * removes the attribute.
172 int key_putattr(key_file
*f
, key
*k
, const char *n
, const char *v
)
177 if (!(f
->f
& KF_WRITE
))
178 return (KERR_READONLY
);
181 a
= sym_find(&k
->a
, n
, -1, sizeof(*a
), &found
);
185 } else if ((a
= sym_find(&k
->a
, n
, -1, 0, 0)) != 0) {
187 sym_remove(&k
->a
, a
);
194 /* --- @key_setcomment@ --- *
196 * Arguments: @key_file *f@ = pointer to key file block
197 * @key *k@ = pointer to key block
198 * @const char *c@ = pointer to comment to set, or zero
200 * Returns: Error code (one of the @KERR@ constants).
202 * Use: Replaces the key's current comment with a new one.
205 int key_setcomment(key_file
*f
, key
*k
, const char *c
)
207 if (!(f
->f
& KF_WRITE
))
208 return (KERR_READONLY
);
209 if (key_chkcomment(c
))
210 return (KERR_BADCOMMENT
);
221 /* --- @key_settag@ --- *
223 * Arguments: @key_file *f@ = pointer to key file block
224 * @key *k@ = pointer to key block
225 * @const char *tag@ = pointer to comment to set, or zero
227 * Returns: Error code (one of the @KERR@ constants).
229 * Use: Replaces the key's current tag with a new one.
232 int key_settag(key_file
*f
, key
*k
, const char *tag
)
237 if (!(f
->f
& KF_WRITE
))
238 return (KERR_READONLY
);
240 /* --- Make sure the tag is OK --- */
242 if (tag
&& key_chkident(tag
))
243 return (KERR_BADTAG
);
245 /* --- See if the new tag is the same as the old one --- */
247 if ((!tag
&& !k
->tag
) ||
248 (tag
&& k
->tag
&& strcmp(tag
, k
->tag
) == 0))
251 /* --- Allocate an entry for the new tag --- */
254 kr
= sym_find(&f
->bytag
, tag
, -1, sizeof(*kr
), &found
);
255 if (found
&& !KEY_EXPIRED(time(0), kr
->k
->del
))
256 return (KERR_DUPTAG
);
260 /* --- Remove any existing tag --- */
263 kr
= sym_find(&f
->bytag
, k
->tag
, -1, 0, 0);
264 assert(((void)"No bytag link", kr
));
265 sym_remove(&f
->bytag
, kr
);
273 k
->tag
= xstrdup(tag
);
279 /* --- @key_fulltag@ --- *
281 * Arguments: @key *k@ = pointer to key
282 * @dstr *d@ = pointer to destination string
286 * Use: Emits the key's full tag, which has the form
287 * `ID:TYPE[:TAG]'. This is used in the textual file format,
288 * and to identify passphrases for locked keys.
291 void key_fulltag(key
*k
, dstr
*d
)
293 dstr_putf(d
, "%08lx:%s", (unsigned long)k
->id
, k
->type
);
295 dstr_putf(d
, ":%s", k
->tag
);
298 /*----- That's all, folks -------------------------------------------------*/