/[winpt]/trunk/Src/wptGPGParser.cpp
ViewVC logotype

Contents of /trunk/Src/wptGPGParser.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (show annotations)
Sun May 7 12:36:48 2006 UTC (18 years, 9 months ago) by twoaday
File size: 11119 byte(s)


1 /* wptGPGParser.cpp - GPG config file parser
2 * Copyright (C) 2002, 2003, 2004, 2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <windows.h>
28
29 #include "wptTypes.h"
30 #include "wptW32API.h"
31 #include "wptGPG.h"
32 #include "wptErrors.h"
33
34 static void
35 add_option (gpg_option_t *list, gpg_option_t n)
36 {
37 gpg_option_t t;
38
39 if (!*list)
40 *list = n;
41 else {
42 for (t = *list; t->next; t = t->next)
43 ;
44 t->next = n;
45 }
46 }
47
48 static gpg_option_t
49 new_option (void)
50 {
51 gpg_option_t e;
52
53 e = new gpg_option_s;
54 if (!e)
55 BUG (0);
56 memset (e, 0, sizeof (e));
57 return e;
58 }
59
60
61 static void
62 add_opaque_option (gpg_optfile_t opt, const char *line, int used)
63 {
64 gpg_option_t e;
65
66 e = new_option ();
67 e->used = used > 0? 1 : 0;
68 e->name = m_strdup (line);
69 e->type = ENTRY_OPAQUE;
70 add_option (&opt->list, e);
71 }
72
73
74 static void
75 add_single_option (gpg_optfile_t opt, const char *name, int used)
76 {
77 gpg_option_t e;
78
79 e = new_option ();
80 e->used = used > 0? 1 : 0;
81 e->name = m_strdup (name);
82 e->type = ENTRY_SINGLE;
83 add_option (&opt->list, e);
84 }
85
86
87 static int
88 add_group_option (gpg_optfile_t opt, const char *name, int used)
89 {
90 gpg_option_t e;
91
92 e = new_option ();
93 e->used = used > 0? 1 : 0;
94 e->name = m_strdup (name);
95 e->type = ENTRY_GROUP;
96 add_option (&opt->list, e);
97 return 0;
98 }
99
100
101 static size_t
102 count_whitespaces (char *line)
103 {
104 size_t i;
105 size_t ncount = 0;
106
107 if (!strchr (line, ' '))
108 return 0;
109 for( i = 0; i < strlen (line); i++) {
110 if (line[i] == ' ')
111 ncount++;
112 }
113 return ncount;
114 }
115
116
117 static int
118 add_multi_option (gpg_optfile_t opt, char *line, int used)
119 {
120 gpg_option_t e;
121 char *p;
122 int state = 0;
123
124 e = new_option ();
125 if (count_whitespaces (line) == 1) {
126 while ((p = strsep (&line, " ")) && state != 2) {
127 switch (state) {
128 case 0: e->name = m_strdup (p); break;
129 case 1: e->val = m_strdup (p); break;
130 }
131 state++;
132 }
133 }
134 else {
135 p = strchr (line, ' ');
136 if (!p)
137 return -1;
138 state = p - line;
139 e->name = new char[state + 1];
140 if (!e->name)
141 BUG (NULL);
142 memcpy (e->name, line, state);
143 e->name[state] = '\0';
144 strncpy (e->name, line, state);
145 e->val = m_strdup (line + state + 1);
146 }
147 e->used = used;
148 e->type = ENTRY_MULTI;
149 add_option (&opt->list, e);
150
151 return 0;
152 }
153
154
155 static gpg_group_t
156 new_group (gpg_group_t *grp, const char *name)
157 {
158 gpg_group_t g, t;
159
160 g = new gpg_group_s;
161 if (!g)
162 BUG (NULL);
163 memset (g, 0, sizeof *g);
164 g->used = 1;
165 g->name = m_strdup (name);
166 if (!*grp)
167 *grp = g;
168 else {
169 for (t = *grp; t->next; t = t->next)
170 ;
171 t->next = g;
172 }
173 return g;
174 }
175
176
177 static const char*
178 group_from_cfgfile (gpg_optfile_t opt, const char *line)
179 {
180 char *p, *buf, *buf2, *name = NULL;
181 gpg_group_t g;
182 gpg_member_t m = NULL, t;
183
184 p = strchr (line, '=');
185 if (!p || strncmp (line, "group ", 6))
186 return NULL;
187 buf = m_strdup (line + (p - line + 1));
188 line += 6;
189 p = strchr (line, '=');
190 if (p) {
191 size_t pos = p - line;
192 name = new char[pos + 1];
193 if (!name)
194 BUG( NULL );
195 memset (name, 0, pos+1);
196 strncpy (name, line, pos);
197 }
198 g = new_group (&opt->grp, name);
199 buf2 = buf;
200 while ((p = strsep (&buf2, " ")) && *p) {
201 m = new gpg_member_s;
202 if (!m)
203 BUG (0);
204 memset (m, 0, sizeof *m);
205 m->used = 1;
206 m->name = m_strdup (p);
207 if (!g->list)
208 g->list = m;
209 else {
210 for (t=g->list; t->next; t = t->next)
211 ;
212 t->next = m;
213 }
214 }
215 free_if_alloc (buf);
216 if (!m)
217 return NULL;
218 return g->name;
219 }
220
221
222 void
223 release_group (gpg_group_t grp)
224 {
225 gpg_member_t m, m2;
226
227 m = grp->list;
228 while (m) {
229 m2 = m->next;
230 free_if_alloc (m->name);
231 free_if_alloc (m);
232 m = m2;
233 }
234 }
235
236
237 void
238 release_option (gpg_option_t opt)
239 {
240 if (!opt)
241 return;
242 free_if_alloc (opt->name);
243 free_if_alloc (opt->val);
244 free_if_alloc (opt );
245 }
246
247
248 void
249 release_gpg_options (gpg_optfile_t opt)
250 {
251 gpg_option_t e, e2;
252 gpg_group_t g, g2;
253
254 e = opt->list;
255 while (e) {
256 e2 = e->next;
257 release_option (e);
258 e = e2;
259 }
260 g = opt->grp;
261 while (g) {
262 g2 = g->next;
263 release_group (g);
264 g = g2;
265 }
266 free_if_alloc (opt);
267 }
268
269
270 int
271 commit_gpg_options (const char *file, gpg_optfile_t opt)
272 {
273 FILE *inp;
274 gpg_option_t e;
275 gpg_group_t g;
276 gpg_member_t m;
277
278 inp = fopen (file, "w+b");
279 if (!inp)
280 return WPTERR_FILE_OPEN;
281 for (e = opt->list; e; e = e->next) {
282 if (!e->used)
283 continue;
284 switch (e->type) {
285 case ENTRY_OPAQUE:
286 fprintf (inp, "%s", e->name);
287 break;
288
289 case ENTRY_MULTI:
290 fprintf (inp, "%s %s\r\n", e->name, e->val);
291 break;
292
293 case ENTRY_SINGLE:
294 fprintf (inp, "%s\r\n", e->name);
295 break;
296
297 case ENTRY_GROUP:
298 g = find_group (opt, e->name);
299 if (g && g->used) {
300 fprintf (inp, "group %s=", g->name);
301 for (m = g->list; m; m = m->next) {
302 if (m->used)
303 fprintf (inp, "%s ", m->name);
304 }
305 fprintf (inp, "\r\n");
306 }
307 break;
308 }
309 }
310 fclose (inp);
311 return 0;
312 }
313
314
315 int
316 parse_gpg_options (const char *file, gpg_optfile_t *r_opt )
317 {
318 FILE *inp;
319 char buf[1024], *p;
320 gpg_optfile_t opt = NULL;
321
322 inp = fopen( file, "rb");
323 if( inp == NULL ) {
324 inp = fopen( file, "wb" );
325 if( inp == NULL )
326 return -1;
327 }
328 opt = new gpg_optfile_s;
329 if( !opt )
330 BUG( NULL );
331 memset( opt, 0, sizeof *opt );
332 while( !feof( inp ) ) {
333 p = fgets( buf, sizeof buf -1, inp );
334 if( !p )
335 break;
336 if( *p == '#' || *p == '\r' || *p == '\n' || *p == '\t' ) {
337 add_opaque_option( opt, p, 1 );
338 continue;
339 }
340 if( strstr( p, "\r\n" ) )
341 p[strlen( p ) - 2] = '\0';
342 else if( strstr( p, "\n" ) )
343 p[strlen( p ) - 1] = '\0';
344 if( !strchr( p, ' ' ) )
345 add_single_option( opt, p, 1 );
346 else if( !strncmp( p, "group", 5 ) ) {
347 const char *s = group_from_cfgfile (opt, p);
348 if (s)
349 add_group_option (opt, s, 1);
350 }
351 else
352 add_multi_option (opt, p, 1);
353 }
354 fclose (inp);
355 if (r_opt)
356 *r_opt = opt;
357 return 0;
358 }
359
360
361 gpg_option_t
362 find_option (gpg_optfile_t opt, const char *str)
363 {
364 gpg_option_t e;
365
366 for (e = opt->list; e; e = e->next) {
367 if (e->type == ENTRY_OPAQUE)
368 continue;
369 if (!stricmp (e->name, str))
370 break;
371 }
372
373 return e;
374 }
375
376
377 gpg_group_t
378 find_group (gpg_optfile_t opt, const char *str)
379 {
380 gpg_group_t g;
381
382 for (g = opt->grp; g; g = g->next) {
383 if (!stricmp( g->name, str))
384 break;
385 }
386
387 return g;
388 }
389
390
391 gpg_member_t
392 find_member (gpg_optfile_t opt, const char *grp, const char *str)
393 {
394 gpg_group_t g = find_group (opt, grp);
395 gpg_member_t m;
396
397 if (!g)
398 return NULL;
399
400 for (m = g->list; m; m = m->next) {
401 if (!stricmp (m->name, str))
402 return m;
403 }
404 return NULL;
405 }
406
407
408 int
409 delete_group (gpg_optfile_t opt, const char *str)
410 {
411 gpg_group_t g = find_group (opt, str);
412
413 if (g)
414 g->used = 0;
415 return g? 0 : -1;
416 }
417
418
419 int
420 delete_member (gpg_optfile_t opt, const char *grp, const char *str)
421 {
422 gpg_member_t m = find_member (opt, grp, str);
423
424 if (m)
425 m->used = 0;
426 return m? 0 : -1;
427 }
428
429
430 int
431 delete_option (gpg_optfile_t opt, const char * str)
432 {
433 gpg_option_t e = find_option (opt, str);
434
435 if (e)
436 e->used = 0;
437 return e? 0 : -1;
438 }
439
440
441 int
442 add_entry (gpg_optfile_t opt, int type, const char *name, const char *val)
443 {
444 gpg_option_t e;
445
446 e = new_option ();
447 e->used = 1;
448 e->type = type;
449 e->name = m_strdup (name);
450 e->val = val? m_strdup (val) : NULL;
451 add_option (&opt->list, e);
452 return 0;
453 }
454
455
456 int
457 modify_entry (gpg_optfile_t opt, int type, const char *name, const char *val)
458 {
459 gpg_option_t e;
460 int rc = 0;
461
462 e = find_option (opt, name);
463 if (!e)
464 rc = add_entry (opt, type, name, val);
465 else if (type != ENTRY_SINGLE) {
466 free_if_alloc (e->val);
467 e->val = m_strdup (val);
468 }
469
470 return rc;
471 }
472
473
474 int
475 add_member (gpg_optfile_t opt, const char *grp, const char *str)
476 {
477 gpg_group_t g = find_group (opt, grp);
478 gpg_member_t m, t;
479
480 if (!g)
481 return -1;
482
483 m = new gpg_member_s;
484 if (!m)
485 BUG (NULL);
486 memset (m, 0, sizeof *m);
487 m->used = 1;
488 m->name = m_strdup (str);
489 if( !g->list )
490 g->list = m;
491 else {
492 for( t = g->list; t->next; t = t->next )
493 ;
494 t->next = m;
495 }
496 return 0;
497 }
498
499
500 int
501 add_group (gpg_optfile_t opt, const char *str)
502 {
503 gpg_group_t g, t;
504
505 g = new gpg_group_s;
506 if (!g)
507 BUG (NULL);
508 memset (g, 0, sizeof *g);
509 g->used = 1;
510 g->name = m_strdup (str);
511
512 if (!opt->grp)
513 opt->grp = g;
514 else {
515 for (t = opt->grp; t->next; t = t->next)
516 ;
517 t->next = g;
518 }
519 add_entry (opt, ENTRY_GROUP, str, NULL);
520 return 0;
521 }
522
523
524 #if 0
525 void
526 walk_group( const char *name, gpg_member_t mbr )
527 {
528 gpg_member_t m;
529
530 printf( "name=%s\n", name );
531 for( m = mbr; m; m = m->next )
532 printf( "%s\n", m->name );
533 }
534
535
536 int
537 main( int argc, char **argv )
538 {
539 int rc;
540 gpg_optfile_t opt;
541 gpg_group_t g;
542 gpg_option_t e;
543
544 rc = parse_gpg_options( "c:\\gnupg\\gpg.conf", &opt );
545 if( rc )
546 printf( "parse_option: error\n" );
547 else {
548 #if 0
549 /*delete_option( opt, "encrypt-to" );*/
550 delete_member( opt, "bar", "richard" );
551 add_member( opt, "bar", "leo" );
552 add_group( opt, "foobar" );
553 delete_group( opt, "foobar" );
554 add_entry( opt, ENTRY_SINGLE, "use-agent", NULL );
555 #endif
556 for( e = opt->list; e; e = e->next ) {
557 if( e->type != 1 )
558 printf( "%d: %s %s\n", e->used, e->name, e->val );
559 }
560 /*commit_gpg_options( "c:\\gnupg\\gpg2.conf", opt );*/
561 for( g = opt->grp; g; g = g->next )
562 walk_group( g->name, g->list );
563 release_option( opt );
564 }
565
566 return 0;
567 }
568 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26