/src/gnupg/common/server-help.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* server-help.h - Helper functions for writing Assuan servers. |
2 | | * Copyright (C) 2003, 2009, 2010 g10 Code GmbH |
3 | | * |
4 | | * This file is part of GnuPG. |
5 | | * |
6 | | * This file is free software; you can redistribute it and/or modify |
7 | | * it under the terms of either |
8 | | * |
9 | | * - the GNU Lesser General Public License as published by the Free |
10 | | * Software Foundation; either version 3 of the License, or (at |
11 | | * your option) any later version. |
12 | | * |
13 | | * or |
14 | | * |
15 | | * - the GNU General Public License as published by the Free |
16 | | * Software Foundation; either version 2 of the License, or (at |
17 | | * your option) any later version. |
18 | | * |
19 | | * or both in parallel, as here. |
20 | | * |
21 | | * This file is distributed in the hope that it will be useful, |
22 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
24 | | * GNU General Public License for more details. |
25 | | * |
26 | | * You should have received a copy of the GNU General Public License |
27 | | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
28 | | */ |
29 | | |
30 | | #include <config.h> |
31 | | #include <string.h> |
32 | | |
33 | | #include "util.h" |
34 | | #include "server-help.h" |
35 | | |
36 | | |
37 | | static GPGRT_INLINE gpg_error_t |
38 | | my_error (int e) |
39 | 0 | { |
40 | 0 | return gpg_err_make (default_errsource, (e)); |
41 | 0 | } |
42 | | |
43 | | static GPGRT_INLINE gpg_error_t |
44 | | my_error_from_syserror (void) |
45 | 0 | { |
46 | 0 | return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); |
47 | 0 | } |
48 | | |
49 | | |
50 | | /* Skip over options in LINE. |
51 | | |
52 | | Blanks after the options are also removed. Options are indicated |
53 | | by two leading dashes followed by a string consisting of non-space |
54 | | characters. The special option "--" indicates an explicit end of |
55 | | options; all what follows will not be considered an option. The |
56 | | first no-option string also indicates the end of option parsing. */ |
57 | | char * |
58 | | skip_options (const char *line) |
59 | 0 | { |
60 | 0 | while (spacep (line)) |
61 | 0 | line++; |
62 | 0 | while (*line == '-' && line[1] == '-') |
63 | 0 | { |
64 | 0 | while (*line && !spacep (line)) |
65 | 0 | line++; |
66 | 0 | while (spacep (line)) |
67 | 0 | line++; |
68 | 0 | } |
69 | 0 | return (char*) line; |
70 | 0 | } |
71 | | |
72 | | |
73 | | /* Check whether the option NAME appears in LINE. */ |
74 | | int |
75 | | has_option (const char *line, const char *name) |
76 | 0 | { |
77 | 0 | const char *s; |
78 | 0 | int n = strlen (name); |
79 | |
|
80 | 0 | s = strstr (line, name); |
81 | 0 | if (s && s >= skip_options (line)) |
82 | 0 | return 0; |
83 | 0 | return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); |
84 | 0 | } |
85 | | |
86 | | |
87 | | /* Same as has_option but only considers options at the begin of the |
88 | | line. This is useful for commands which allow arbitrary strings on |
89 | | the line. */ |
90 | | int |
91 | | has_leading_option (const char *line, const char *name) |
92 | 0 | { |
93 | 0 | const char *s; |
94 | 0 | int n; |
95 | |
|
96 | 0 | if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2)) |
97 | 0 | return 0; |
98 | 0 | n = strlen (name); |
99 | 0 | while ( *line == '-' && line[1] == '-' ) |
100 | 0 | { |
101 | 0 | s = line; |
102 | 0 | while (*line && !spacep (line)) |
103 | 0 | line++; |
104 | 0 | if (n == (line - s) && !strncmp (s, name, n)) |
105 | 0 | return 1; |
106 | 0 | while (spacep (line)) |
107 | 0 | line++; |
108 | 0 | } |
109 | 0 | return 0; |
110 | 0 | } |
111 | | |
112 | | |
113 | | /* Same as has_option but does only test for the name of the option |
114 | | and ignores an argument, i.e. with NAME being "--hash" it would |
115 | | return a pointer for "--hash" as well as for "--hash=foo". If |
116 | | there is no such option NULL is returned. The pointer returned |
117 | | points right behind the option name, this may be an equal sign, Nul |
118 | | or a space. */ |
119 | | const char * |
120 | | has_option_name (const char *line, const char *name) |
121 | 0 | { |
122 | 0 | const char *s; |
123 | 0 | int n = strlen (name); |
124 | |
|
125 | 0 | s = strstr (line, name); |
126 | 0 | return (s && (s == line || spacep (s-1)) |
127 | 0 | && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; |
128 | 0 | } |
129 | | |
130 | | |
131 | | /* Parse an option with the format "--NAME=VALUE" which must occur in |
132 | | * LINE before a double-dash. LINE is written to but not modified by |
133 | | * this function. If the option is found and has a value the value is |
134 | | * stored as a malloced string at R_VALUE. If the option was not |
135 | | * found or an error occurred NULL is stored there. Note that |
136 | | * currently the value must be a string without any space; we may |
137 | | * eventually update this function to allow for a quoted value. */ |
138 | | gpg_error_t |
139 | | get_option_value (char *line, const char *name, char **r_value) |
140 | 0 | { |
141 | 0 | char *p, *pend; |
142 | 0 | int c; |
143 | |
|
144 | 0 | *r_value = NULL; |
145 | |
|
146 | 0 | p = (char*)has_option_name (line, name); |
147 | 0 | if (!p || p >= skip_options (line)) |
148 | 0 | return 0; |
149 | | |
150 | 0 | if (*p != '=' || !p[1] || spacep (p+1)) |
151 | 0 | return my_error (GPG_ERR_INV_ARG); |
152 | 0 | p++; |
153 | 0 | for (pend = p; *pend && !spacep (pend); pend++) |
154 | 0 | ; |
155 | 0 | c = *pend; |
156 | 0 | *pend = 0; |
157 | 0 | *r_value = xtrystrdup (p); |
158 | 0 | *pend = c; |
159 | 0 | if (!p) |
160 | 0 | return my_error_from_syserror (); |
161 | 0 | return 0; |
162 | 0 | } |
163 | | |
164 | | |
165 | | /* Return a pointer to the argument of the option with NAME. If such |
166 | | an option is not given, NULL is returned. */ |
167 | | char * |
168 | | option_value (const char *line, const char *name) |
169 | 0 | { |
170 | 0 | char *s; |
171 | 0 | int n = strlen (name); |
172 | |
|
173 | 0 | s = strstr (line, name); |
174 | 0 | if (s && s >= skip_options (line)) |
175 | 0 | return NULL; |
176 | 0 | if (s && (s == line || spacep (s-1)) |
177 | 0 | && s[n] && (spacep (s+n) || s[n] == '=')) |
178 | 0 | { |
179 | 0 | s += n + 1; |
180 | 0 | s += strspn (s, " "); |
181 | 0 | if (*s && !spacep(s)) |
182 | 0 | return s; |
183 | 0 | } |
184 | 0 | return NULL; |
185 | 0 | } |