]> the.earth.li Git - onak.git/blob - keyarray.c
Fix compilation with later versions of Nettle
[onak.git] / keyarray.c
1 /*
2  * keyarray.c - routines to maintain a sorted array of keyids.
3  *
4  * Copyright 2004 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <ctype.h>
20 #include <errno.h>
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "keyarray.h"
28 #include "keystructs.h"
29
30 int fingerprint_cmp(struct openpgp_fingerprint *a,
31                 struct openpgp_fingerprint *b)
32 {
33         if (a->length < b->length) {
34                 return -1;
35         } else if (a->length > b->length) {
36                 return 1;
37         } else {
38                 return memcmp(a->fp, b->fp, a->length);
39         }
40 }
41
42 bool array_find(struct keyarray *array, struct openpgp_fingerprint *fp)
43 {
44         bool found;
45         int  top = 0;
46         int  bottom = 0;
47         int  curpos;
48
49         found = false;
50         if (array->keys != NULL && array->count > 0) {
51                 bottom = -1;
52                 top = array->count - 1;
53                 while ((top - bottom) > 1) {
54                         curpos = (top + bottom) / 2;
55                         if (fingerprint_cmp(fp, &array->keys[curpos]) > 0) {
56                                 bottom = curpos;
57                         } else {
58                                 top = curpos;
59                         }
60                 }
61                 found = (fingerprint_cmp(fp, &array->keys[top]) == 0);
62         }
63
64         return found;
65 }
66
67 bool array_add(struct keyarray *array, struct openpgp_fingerprint *fp)
68 {
69         bool found;
70         int  top = 0;
71         int  bottom = 0;
72         int  curpos = 0;
73
74         found = false;
75         if (array->size != 0 && array->count > 0) {
76                 bottom = -1;
77                 top = array->count - 1;
78                 while ((top - bottom) > 1) {
79                         curpos = (top + bottom) / 2;
80                         if (fingerprint_cmp(fp, &array->keys[curpos]) > 0) {
81                                 bottom = curpos;
82                         } else {
83                                 top = curpos;
84                         }
85                 }
86                 found = (fingerprint_cmp(fp, &array->keys[top]) == 0);
87
88                 if (fingerprint_cmp(fp, &array->keys[top]) > 0) {
89                         curpos = top + 1;
90                 } else {
91                         curpos = top;
92                 }
93         }
94
95         if (!found) {
96                 if (array->size == 0) {
97                         array->keys = malloc(16 *
98                                 sizeof(struct openpgp_fingerprint));
99                         array->size = 16;
100                         array->count = 1;
101                         array->keys[0] = *fp;
102                 } else {
103                         if (array->count >= array->size) {
104                                 array->size *= 2;
105                                 array->keys = realloc(array->keys,
106                                         array->size *
107                                         sizeof(struct openpgp_fingerprint));
108                         }
109                         if (curpos < array->count) {
110                                 memmove(&array->keys[curpos+1],
111                                         &array->keys[curpos],
112                                         sizeof(struct openpgp_fingerprint) *
113                                                 (array->count - curpos));
114                         }
115                         array->keys[curpos] = *fp;
116                         array->count++;
117                 }
118         }
119
120         return !found;
121 }
122
123 void array_free(struct keyarray *array)
124 {
125         if (array->keys) {
126                 free(array->keys);
127                 array->keys = NULL;
128         }
129         array->count = array->size = 0;
130
131         return;
132 }
133
134 static uint8_t hex2bin(char c)
135 {
136         if (c >= '0' && c <= '9') {
137                 return (c - '0');
138         } else if (c >= 'a' && c <= 'f') {
139                 return (c - 'a' + 10);
140         } else if (c >= 'A' && c <= 'F') {
141                 return (c - 'A' + 10);
142         }
143
144         return 255;
145 }
146
147 bool array_load(struct keyarray *array, const char *file)
148 {
149         struct openpgp_fingerprint fp;
150         char curline[1024];
151         FILE *fpfile;
152         int i;
153
154         fpfile = fopen(file, "r");
155
156         if (fpfile != NULL) {
157                 if (!fgets(curline, sizeof(curline) - 1, fpfile)) {
158                         fclose(fpfile);
159                         return false;
160                 }
161
162                 while (!feof(fpfile)) {
163                         /* Strip any trailing white space */
164                         for (i = strlen(curline) - 1;
165                                         i >= 0 && isspace(curline[i]); i--) {
166                                 curline[i] = 0;
167                         }
168                         i++;
169                         //if ((i % 2) != 0) {
170                         //      break;
171                         //}
172                         i >>= 1;
173                         if (curline[0] == '#') {
174                                 // Comment line, ignore
175                         } else if (i == FINGERPRINT_V3_LEN ||
176                                         i == FINGERPRINT_V4_LEN ||
177                                         i == FINGERPRINT_V5_LEN) {
178                                 fp.length = i;
179                                 for (i = 0; i < fp.length; i++) {
180                                         fp.fp[i] = hex2bin(curline[i * 2]);
181                                         fp.fp[i] <<= 4;
182                                         fp.fp[i] |=
183                                                 hex2bin(curline[i * 2 + 1]);
184                                 }
185                                 array_add(array, &fp);
186                         } else {
187                                 printf("Bad line.\n");
188                         }
189
190                         if (!fgets(curline, sizeof(curline) - 1, fpfile)) {
191                                 break;
192                         }
193                 }
194
195                 fclose(fpfile);
196         }
197
198         return (array->count != 0);
199 }