New function for division by a small integer.
[u/mdw/catacomb] / key-flags.c
1 /* -*-c-*-
2 *
3 * $Id: key-flags.c,v 1.1 1999/12/22 15:47:48 mdw Exp $
4 *
5 * Reading and writing key flag strings
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-flags.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 <stdlib.h>
41 #include <string.h>
42
43 #include <mLib/bits.h>
44 #include <mLib/dstr.h>
45
46 #include "key.h"
47
48 /*----- Data structures ---------------------------------------------------*/
49
50 typedef struct key_flags {
51 unsigned f;
52 unsigned m;
53 } key_flags;
54
55 /*----- Flags table -------------------------------------------------------*/
56
57 typedef struct flagent {
58 const char *name;
59 unsigned f;
60 unsigned m;
61 } flagent;
62
63 static flagent flagtab[] = {
64
65 /* --- Encoding types --- */
66
67 { "binary", KENC_BINARY, KF_ENCMASK },
68 { "integer", KENC_MP, KF_ENCMASK },
69 { "struct", KENC_STRUCT, KF_ENCMASK },
70 { "encrypt", KENC_ENCRYPT, KF_ENCMASK },
71
72 /* --- Classes of keys --- */
73
74 { "shared", KCAT_SHARE, KF_CATMASK },
75 { "public", KCAT_PUB, KF_CATMASK },
76 { "private", KCAT_PRIV, KF_CATMASK },
77 { "symmetric", KCAT_SYMM, KF_CATMASK },
78 { "secret", 0, KF_NONSECRET },
79 { "-secret", KF_NONSECRET, KF_NONSECRET },
80
81 /* --- Other flags --- */
82
83 { "burn", KF_BURN, KF_BURN },
84 { "-burn", 0, KF_BURN },
85
86 /* --- End marker --- */
87
88 { 0, 0, 0 }
89 };
90
91 /*----- Main code ---------------------------------------------------------*/
92
93 /* --- @key_readflags@ --- *
94 *
95 * Arguments: @const char *p@ = pointer to string to read
96 * @char **pp@ = where to store the end pointer
97 * @unsigned *ff@ = where to store the flags
98 * @unsigned *mm@ = where to store the mask
99 *
100 * Returns: Zero if all went well, nonzero if there was an error.
101 *
102 * Use: Reads a flag string.
103 */
104
105 int key_readflags(const char *p, char **pp, unsigned *ff, unsigned *mm)
106 {
107 unsigned f = 0, m = 0;
108
109 for (;;) {
110 size_t sz = strcspn(p, ",:");
111 flagent *e, *ee = 0;
112
113 /* --- Look up the string in the flags table --- */
114
115 for (e = flagtab; e->name; e++) {
116 if (strncmp(e->name, p, sz) == 0) {
117 if (e->name[sz] == 0) {
118 ee = e;
119 break;
120 } else if (ee)
121 return (KERR_BADFLAGS);
122 else
123 ee = e;
124 }
125 }
126 if (!ee)
127 return (KERR_BADFLAGS);
128
129 /* --- Adjust the flag words --- *
130 *
131 * Ensure that the flags set are disjoint.
132 */
133
134 if (m & ee->m)
135 return (KERR_BADFLAGS);
136 m |= ee->m;
137 f |= ee->f;
138 p += sz;
139 if (*p == 0 || *p == ':')
140 break;
141 p++;
142 }
143
144 /* --- Report the results --- */
145
146 if (ff) *ff = f;
147 if (mm) *mm = m;
148 if (pp) *pp = (char *)p;
149 return (0);
150 }
151
152 /* --- @key_writeflags@ --- *
153 *
154 * Arguments: @unsigned f@ = flags to write
155 * @dstr *d@ = pointer to destination string
156 *
157 * Returns: ---
158 *
159 * Use: Emits a flags word as a string representation.
160 */
161
162 void key_writeflags(unsigned f, dstr *d)
163 {
164 int del = 0;
165 flagent *e;
166 unsigned m = 0;
167
168 for (e = flagtab; e->name; e++) {
169 if (m & e->m || e->name[0] == '-' || (f & e->m) != e->f)
170 continue;
171 if (del)
172 DPUTC(d, ',');
173 DPUTS(d, e->name);
174 m |= e->m;
175 del = 1;
176 }
177 }
178
179 /*----- That's all, folks -------------------------------------------------*/