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>
41 /*----- Main code ---------------------------------------------------------*/
43 /* --- @key_chkident@ --- *
45 * Arguments: @const char *p@ = pointer to a type string
47 * Returns: Zero if OK, -1 on error.
49 * Use: Checks whether an identification component string is OK.
52 int key_chkident(const char *p
)
54 if (!p
|| !*p
|| strlen(p
) > 255)
57 if (*p
== ':' || *p
== '.' || isspace((unsigned char)*p
))
64 /* --- @key_chkcomment@ --- *
66 * Arguments: @const char *p@ = pointer to a comment string
68 * Returns: Zero if OK, -1 on error.
70 * Use: Checks whether a comment string is OK.
73 int key_chkcomment(const char *p
)
87 /* --- @key_mkattriter@ --- *
89 * Arguments: @key_attriter *i@ = pointer to attribute iterator
90 * @key *k@ = pointer to key
94 * Use: Initializes an attribute iterator. The attributes are
95 * returned by @key_nextattr@.
98 void key_mkattriter(key_attriter
*i
, key
*k
)
100 sym_mkiter(&i
->i
, &k
->a
);
103 /* --- @key_nextattr@ --- *
105 * Arguments: @key_attriter *i@ = pointer to attribute iterator
106 * @const char **n, **v@ = pointers to name and value
108 * Returns: Zero if no attribute available, or nonzero if returned OK.
110 * Use: Returns the next attribute.
113 int key_nextattr(key_attriter
*i
, const char **n
, const char **v
)
115 key_attr
*a
= sym_next(&i
->i
);
118 if (n
) *n
= SYM_NAME(a
);
123 /* --- @key_getattr@ --- *
125 * Arguments: @key_file *f@ = pointer to file
126 * @key *k@ = pointer to key
127 * @const char *n@ = pointer to attribute name
129 * Returns: Pointer to attribute value, or null if not found.
131 * Use: Returns the value of a key attribute.
134 const char *key_getattr(key_file
*f
, key
*k
, const char *n
)
137 if ((a
= sym_find(&k
->a
, n
, -1, 0, 0)) == 0)
142 /* --- @key_putattr@ --- *
144 * Arguments: @key_file *f@ = pointer to file
145 * @key *k@ = pointer to key
146 * @const char *n@ = pointer to attribute name
147 * @const char *v@ = pointer to attribute value or null
149 * Returns: Error code (one of the @KERR@ constants).
151 * Use: Inserts an attribute on a key. If an attribute with the same
152 * name already exists, it is deleted. Setting a null value
153 * removes the attribute.
156 int key_putattr(key_file
*f
, key
*k
, const char *n
, const char *v
)
161 if (!(f
->f
& KF_WRITE
))
162 return (KERR_READONLY
);
164 return (KERR_BADATTR
);
167 a
= sym_find(&k
->a
, n
, -1, sizeof(*a
), &found
);
171 } else if ((a
= sym_find(&k
->a
, n
, -1, 0, 0)) != 0) {
173 sym_remove(&k
->a
, a
);
180 /* --- @key_setkeydata@ --- *
182 * Arguments: @key_file *kf@ = pointer to key file
183 * @key *k@ = pointer to key
184 * @key_data *kd@ = new key data
186 * Returns: Zero on success, or a @KERR_@ error code on failure.
188 * Use: Sets the key data for a key.
191 int key_setkeydata(key_file
*kf
, key
*k
, key_data
*kd
)
193 if (!(kf
->f
& KF_WRITE
))
194 return (KERR_READONLY
);
198 kf
->f
|= KF_MODIFIED
;
202 /* --- @key_setcomment@ --- *
204 * Arguments: @key_file *f@ = pointer to key file block
205 * @key *k@ = pointer to key block
206 * @const char *c@ = pointer to comment to set, or zero
208 * Returns: Error code (one of the @KERR@ constants).
210 * Use: Replaces the key's current comment with a new one.
213 int key_setcomment(key_file
*f
, key
*k
, const char *c
)
215 if (!(f
->f
& KF_WRITE
))
216 return (KERR_READONLY
);
217 if (key_chkcomment(c
))
218 return (KERR_BADCOMMENT
);
229 /* --- @key_settag@ --- *
231 * Arguments: @key_file *f@ = pointer to key file block
232 * @key *k@ = pointer to key block
233 * @const char *tag@ = pointer to comment to set, or zero
235 * Returns: Error code (one of the @KERR@ constants).
237 * Use: Replaces the key's current tag with a new one.
240 int key_settag(key_file
*f
, key
*k
, const char *tag
)
245 if (!(f
->f
& KF_WRITE
))
246 return (KERR_READONLY
);
248 /* --- Make sure the tag is OK --- */
250 if (tag
&& key_chkident(tag
))
251 return (KERR_BADTAG
);
253 /* --- See if the new tag is the same as the old one --- */
255 if ((!tag
&& !k
->tag
) ||
256 (tag
&& k
->tag
&& strcmp(tag
, k
->tag
) == 0))
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 -------------------------------------------------*/