Line data Source code
1 : /* t-exectool.c - Module test for exectool.c
2 : * Copyright (C) 2016 g10 Code GmbH
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 3 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, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <errno.h>
24 : #include <assert.h>
25 : #include <unistd.h>
26 :
27 : #include "util.h"
28 : #include "exectool.h"
29 :
30 : static int verbose;
31 :
32 : #define fail(msg, err) \
33 : do { fprintf (stderr, "%s:%d: %s failed: %s\n", \
34 : __FILE__,__LINE__, (msg), gpg_strerror (err)); \
35 : exit (1); \
36 : } while(0)
37 :
38 : static void
39 1 : test_executing_true (void)
40 : {
41 : gpg_error_t err;
42 1 : const char *argv[] = { "/bin/true", NULL };
43 : char *result;
44 : size_t len;
45 :
46 1 : if (access (argv[0], X_OK))
47 : {
48 0 : fprintf (stderr, "skipping test: %s not executable: %s",
49 0 : argv[0], strerror (errno));
50 1 : return;
51 : }
52 :
53 1 : if (verbose)
54 0 : fprintf (stderr, "Executing %s...\n", argv[0]);
55 :
56 1 : err = gnupg_exec_tool (argv[0], &argv[1], "", &result, &len);
57 1 : if (err)
58 0 : fail ("gnupg_exec_tool", err);
59 :
60 1 : assert (result);
61 1 : assert (len == 0);
62 1 : free (result);
63 : }
64 :
65 : static void
66 1 : test_executing_false (void)
67 : {
68 : gpg_error_t err;
69 1 : const char *argv[] = { "/bin/false", NULL };
70 : char *result;
71 : size_t len;
72 :
73 1 : if (access (argv[0], X_OK))
74 : {
75 0 : fprintf (stderr, "skipping test: %s not executable: %s",
76 0 : argv[0], strerror (errno));
77 1 : return;
78 : }
79 :
80 1 : if (verbose)
81 0 : fprintf (stderr, "Executing %s...\n", argv[0]);
82 :
83 1 : err = gnupg_exec_tool (argv[0], &argv[1], "", &result, &len);
84 1 : assert (err == GPG_ERR_GENERAL);
85 : }
86 :
87 : static void
88 2 : test_executing_cat (const char *vector)
89 : {
90 : gpg_error_t err;
91 2 : const char *argv[] = { "/bin/cat", NULL };
92 : char *result;
93 : size_t len;
94 :
95 2 : if (access (argv[0], X_OK))
96 : {
97 0 : fprintf (stderr, "skipping test: %s not executable: %s",
98 0 : argv[0], strerror (errno));
99 2 : return;
100 : }
101 :
102 2 : if (verbose)
103 0 : fprintf (stderr, "Executing %s...\n", argv[0]);
104 :
105 2 : err = gnupg_exec_tool (argv[0], &argv[1], vector, &result, &len);
106 2 : if (err)
107 0 : fail ("gnupg_exec_tool", err);
108 :
109 2 : assert (result);
110 :
111 : /* gnupg_exec_tool returns the correct length... */
112 2 : assert (len == strlen (vector));
113 : /* ... but 0-terminates data for ease of use. */
114 2 : assert (result[len] == 0);
115 :
116 2 : assert (strcmp (result, vector) == 0);
117 2 : free (result);
118 : }
119 :
120 :
121 : static void
122 1 : test_catting_cat (void)
123 : {
124 : gpg_error_t err;
125 1 : const char *argv[] = { "/bin/cat", "/bin/cat", NULL };
126 : char *result;
127 : size_t len;
128 : estream_t in;
129 : char *reference, *p;
130 : size_t reference_len;
131 :
132 1 : if (access (argv[0], X_OK))
133 : {
134 0 : fprintf (stderr, "skipping test: %s not executable: %s",
135 0 : argv[0], strerror (errno));
136 0 : return;
137 : }
138 :
139 1 : in = es_fopen (argv[1], "r");
140 1 : if (in == NULL)
141 : {
142 0 : fprintf (stderr, "skipping test: could not open %s: %s",
143 0 : argv[1], strerror (errno));
144 0 : return;
145 : }
146 :
147 1 : err = es_fseek (in, 0L, SEEK_END);
148 1 : if (err)
149 : {
150 0 : fprintf (stderr, "skipping test: could not seek in %s: %s",
151 : argv[1], gpg_strerror (err));
152 0 : return;
153 : }
154 :
155 1 : reference_len = es_ftell (in);
156 1 : err = es_fseek (in, 0L, SEEK_SET);
157 1 : assert (!err || !"rewinding failed");
158 :
159 1 : reference = malloc (reference_len);
160 1 : assert (reference || !"allocating reference buffer failed");
161 :
162 15 : for (p = reference; p - reference < reference_len; )
163 : {
164 : size_t bytes_read, left;
165 13 : left = reference_len - (p - reference);
166 13 : if (left > 4096)
167 12 : left = 4096;
168 13 : err = es_read (in, p, left, &bytes_read);
169 13 : if (err)
170 : {
171 0 : fprintf (stderr, "error reading %s: %s",
172 : argv[1], gpg_strerror (err));
173 0 : exit (1);
174 : }
175 :
176 13 : p += bytes_read;
177 : }
178 1 : es_fclose (in);
179 :
180 1 : if (verbose)
181 0 : fprintf (stderr, "Executing %s %s...\n", argv[0], argv[1]);
182 :
183 1 : err = gnupg_exec_tool (argv[0], &argv[1], "", &result, &len);
184 1 : if (err)
185 0 : fail ("gnupg_exec_tool", err);
186 :
187 1 : assert (result);
188 :
189 : /* gnupg_exec_tool returns the correct length... */
190 1 : assert (len == reference_len);
191 1 : assert (memcmp (result, reference, reference_len) == 0);
192 1 : free (reference);
193 1 : free (result);
194 : }
195 :
196 :
197 : int
198 1 : main (int argc, char **argv)
199 : {
200 : int i;
201 : char binjunk[256];
202 :
203 1 : if (argc)
204 1 : { argc--; argv++; }
205 1 : if (argc && !strcmp (argv[0], "--verbose"))
206 : {
207 0 : verbose = 1;
208 0 : argc--; argv++;
209 : }
210 :
211 1 : test_executing_true ();
212 1 : test_executing_false ();
213 1 : test_executing_cat ("Talking to myself here...");
214 :
215 256 : for (i = 0; i < 255 /* one less */; i++)
216 255 : binjunk[i] = i + 1; /* avoid 0 */
217 1 : binjunk[255] = 0;
218 :
219 1 : test_executing_cat (binjunk);
220 1 : test_catting_cat ();
221 :
222 1 : return 0;
223 : }
|