* ksutil.c (parse_ks_options): Handle verbose=nnn.
[gnupg.git] / keyserver / ksutil.c
1 /* ksutil.c - general keyserver utility functions
2  * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <signal.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "keyserver.h"
28 #include "ksutil.h"
29
30 static void
31 catch_alarm(int foo)
32 {
33   _exit(KEYSERVER_TIMEOUT);
34 }
35
36 unsigned int
37 set_timeout(unsigned int seconds)
38 {
39 #ifdef HAVE_DOSISH_SYSTEM
40   return 0;
41 #else
42   return alarm(seconds);
43 #endif
44 }
45
46 int
47 register_timeout(void)
48 {
49 #ifdef HAVE_DOSISH_SYSTEM
50   return 0;
51 #else
52 #if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
53   struct sigaction act;
54
55   act.sa_handler=catch_alarm;
56   sigemptyset(&act.sa_mask);
57   act.sa_flags=0;
58   return sigaction(SIGALRM,&act,NULL);
59 #else 
60   if(signal(SIGALRM,catch_alarm)==SIG_ERR)
61     return -1;
62   else
63     return 0;
64 #endif
65 #endif
66 }
67
68 struct ks_options *
69 init_ks_options(void)
70 {
71   struct ks_options *opt;
72
73   opt=calloc(1,sizeof(struct ks_options));
74
75   if(opt)
76     {
77       opt->action=KS_UNKNOWN;
78       opt->flags.check_cert=1;
79       opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
80     }
81
82   return opt;
83 }
84
85 void
86 free_ks_options(struct ks_options *opt)
87 {
88   if(opt)
89     {
90       free(opt->host);
91       free(opt->port);
92       free(opt->scheme);
93       free(opt->auth);
94       free(opt->path);
95       free(opt->opaque);
96       free(opt->ca_cert_file);
97       free(opt);
98     }
99 }
100
101 /* Returns 0 if we "ate" the line.  Returns >0, a KEYSERVER_ error
102    code if that error applies.  Returns -1 if we did not match the
103    line at all. */
104 int
105 parse_ks_options(char *line,struct ks_options *opt)
106 {
107   int version;
108   char command[MAX_COMMAND+1];
109   char host[MAX_HOST+1];
110   char port[MAX_PORT+1];
111   char scheme[MAX_SCHEME+1];
112   char auth[MAX_AUTH+1];
113   char path[URLMAX_PATH+1];
114   char opaque[MAX_OPAQUE+1];
115   char option[MAX_OPTION+1];
116
117   if(line[0]=='#')
118     return 0;
119
120   if(sscanf(line,"COMMAND %" MKSTRING(MAX_COMMAND) "s\n",command)==1)
121     {
122       command[MAX_COMMAND]='\0';
123
124       if(strcasecmp(command,"get")==0)
125         opt->action=KS_GET;
126       else if(strcasecmp(command,"send")==0)
127         opt->action=KS_SEND;
128       else if(strcasecmp(command,"search")==0)
129         opt->action=KS_SEARCH;
130
131       return 0;
132     }
133
134   if(sscanf(line,"HOST %" MKSTRING(MAX_HOST) "s\n",host)==1)
135     {
136       host[MAX_HOST]='\0';
137       opt->host=strdup(host);
138       if(!opt->host)
139         return KEYSERVER_NO_MEMORY;
140       return 0;
141     }
142
143   if(sscanf(line,"PORT %" MKSTRING(MAX_PORT) "s\n",port)==1)
144     {
145       port[MAX_PORT]='\0';
146       opt->port=strdup(port);
147       if(!opt->port)
148         return KEYSERVER_NO_MEMORY;
149       return 0;
150     }
151
152   if(sscanf(line,"SCHEME %" MKSTRING(MAX_SCHEME) "s\n",scheme)==1)
153     {
154       scheme[MAX_SCHEME]='\0';
155       opt->scheme=strdup(scheme);
156       if(!opt->scheme)
157         return KEYSERVER_NO_MEMORY;
158       return 0;
159     }
160
161   if(sscanf(line,"AUTH %" MKSTRING(MAX_AUTH) "s\n",auth)==1)
162     {
163       auth[MAX_AUTH]='\0';
164       opt->auth=strdup(auth);
165       if(!opt->auth)
166         return KEYSERVER_NO_MEMORY;
167       return 0;
168     }
169
170   if(sscanf(line,"PATH %" MKSTRING(URLMAX_PATH) "s\n",path)==1)
171     {
172       path[URLMAX_PATH]='\0';
173       opt->path=strdup(path);
174       if(!opt->path)
175         return KEYSERVER_NO_MEMORY;
176       return 0;
177     }
178
179   if(sscanf(line,"OPAQUE %" MKSTRING(MAX_OPAQUE) "s\n",opaque)==1)
180     {
181       opaque[MAX_OPAQUE]='\0';
182       opt->opaque=strdup(opaque);
183       if(!opt->opaque)
184         return KEYSERVER_NO_MEMORY;
185       return 0;
186     }
187
188   if(sscanf(line,"VERSION %d\n",&version)==1)
189     {
190       if(version!=KEYSERVER_PROTO_VERSION)
191         return KEYSERVER_VERSION_ERROR;
192
193       return 0;
194     }
195
196   if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",option)==1)
197     {
198       int no=0;
199       char *start=&option[0];
200
201       option[MAX_OPTION]='\0';
202
203       if(strncasecmp(option,"no-",3)==0)
204         {
205           no=1;
206           start=&option[3];
207         }
208
209       if(strncasecmp(start,"verbose",7)==0)
210         {
211           if(no)
212             opt->verbose=0;
213           else if(start[7]=='=')
214             opt->verbose=atoi(&start[8]);
215           else
216             opt->verbose++;
217         }
218       else if(strcasecmp(start,"include-disabled")==0)
219         {
220           if(no)
221             opt->flags.include_disabled=0;
222           else
223             opt->flags.include_disabled=1;
224         }
225       else if(strcasecmp(start,"include-revoked")==0)
226         {
227           if(no)
228             opt->flags.include_revoked=0;
229           else
230             opt->flags.include_revoked=1;
231         }
232       else if(strcasecmp(start,"include-subkeys")==0)
233         {
234           if(no)
235             opt->flags.include_subkeys=0;
236           else
237             opt->flags.include_subkeys=1;
238         }
239       else if(strcasecmp(start,"check-cert")==0)
240         {
241           if(no)
242             opt->flags.check_cert=0;
243           else
244             opt->flags.check_cert=1;
245         }
246       else if(strncasecmp(start,"debug",5)==0)
247         {
248           if(no)
249             opt->debug=0;
250           else if(start[5]=='=')
251             opt->debug=atoi(&start[6]);
252           else if(start[5]=='\0')
253             opt->debug=1;
254         }
255       else if(strncasecmp(start,"timeout",7)==0)
256         {
257           if(no)
258             opt->timeout=0;
259           else if(start[7]=='=')
260             opt->timeout=atoi(&start[8]);
261           else if(start[7]=='\0')
262             opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
263         }
264       else if(strncasecmp(start,"ca-cert-file",12)==0)
265         {
266           if(no)
267             {
268               free(opt->ca_cert_file);
269               opt->ca_cert_file=NULL;
270             }
271           else if(start[12]=='=')
272             {
273               free(opt->ca_cert_file);
274               opt->ca_cert_file=strdup(&start[13]);
275               if(!opt->ca_cert_file)
276                 return KEYSERVER_NO_MEMORY;
277             }
278         }
279     }
280
281   return -1;
282 }
283
284 const char *
285 ks_action_to_string(enum ks_action action)
286 {
287   switch(action)
288     {
289     case KS_UNKNOWN: return "UNKNOWN";
290     case KS_GET:     return "GET";
291     case KS_SEND:    return "SEND";
292     case KS_SEARCH:  return "SEARCH";
293     }
294
295   return "?";
296 }