Line data Source code
1 : /* pipeconnect.c - Check the assuan_pipe_connect call.
2 : Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
3 :
4 : This file is part of Assuan.
5 :
6 : Assuan is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU Lesser General Public License as
8 : published by the Free Software Foundation; either version 3 of
9 : the License, or (at your option) any later version.
10 :
11 : Assuan is distributed in the hope that it will be useful, but
12 : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should have received a copy of the GNU Lesser General Public
17 : License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : /*
21 : This tests creates a program which starts an assuan server and runs
22 : some simple tests on it. The other program is actually the same
23 : program but called with the option --server.
24 : */
25 :
26 : #ifdef HAVE_CONFIG_H
27 : #include <config.h>
28 : #endif
29 :
30 : #include <stdio.h>
31 : #include <stdlib.h>
32 : #include <string.h>
33 : #include <assert.h>
34 : #include <errno.h>
35 :
36 : #include "../src/assuan.h"
37 : #include "common.h"
38 :
39 : static assuan_fd_t my_stdin = ASSUAN_INVALID_FD;
40 : static assuan_fd_t my_stdout = ASSUAN_INVALID_FD;
41 : static assuan_fd_t my_stderr = ASSUAN_INVALID_FD;
42 :
43 :
44 : static gpg_error_t
45 1 : cmd_echo (assuan_context_t ctx, char *line)
46 : {
47 1 : log_info ("got ECHO command (%s)\n", line);
48 :
49 1 : assuan_send_data (ctx, line, strlen (line));
50 :
51 1 : return 0;
52 : }
53 :
54 :
55 : static gpg_error_t
56 0 : cmd_cat (assuan_context_t ctx, char *line)
57 : {
58 : assuan_fd_t fd, fdout;
59 : int c;
60 : FILE *fp, *fpout;
61 : int nbytes;
62 :
63 0 : log_info ("got CAT command (%s)\n", line);
64 :
65 0 : fd = assuan_get_input_fd (ctx);
66 0 : if (fd == ASSUAN_INVALID_FD)
67 0 : return gpg_error (GPG_ERR_ASS_NO_INPUT);
68 0 : fdout = assuan_get_output_fd (ctx);
69 0 : if (fdout == ASSUAN_INVALID_FD)
70 0 : return gpg_error (GPG_ERR_ASS_NO_OUTPUT);
71 0 : fp = fdopen (fd, "r");
72 0 : if (!fp)
73 : {
74 0 : log_error ("fdopen failed on input fd: %s\n", strerror (errno));
75 0 : return gpg_error (GPG_ERR_ASS_GENERAL);
76 : }
77 :
78 0 : fpout = fdopen (fdout, "w");
79 0 : if (!fpout)
80 : {
81 0 : log_error ("fdopen failed on output fd: %s\n", strerror (errno));
82 0 : fclose (fp);
83 0 : return gpg_error (GPG_ERR_ASS_GENERAL);
84 : }
85 :
86 0 : nbytes = 0;
87 0 : while ( (c=getc (fp)) != -1)
88 : {
89 0 : putc (c, fpout);
90 0 : nbytes++;
91 : }
92 0 : log_info ("done printing %d bytes to output fd\n", nbytes);
93 :
94 : /* Fixme: This also closes the original fd. */
95 0 : fclose (fp);
96 0 : fclose (fpout);
97 0 : return 0;
98 : }
99 :
100 :
101 : static gpg_error_t
102 1 : server_register_commands (assuan_context_t ctx)
103 : {
104 : static struct
105 : {
106 : const char *name;
107 : gpg_error_t (*handler) (assuan_context_t, char *line);
108 : } table[] =
109 : {
110 : { "ECHO", cmd_echo },
111 : { "CAT", cmd_cat },
112 : { "INPUT", NULL },
113 : { "OUTPUT", NULL },
114 : { NULL, NULL }
115 : };
116 : int i;
117 : gpg_error_t rc;
118 :
119 5 : for (i=0; table[i].name; i++)
120 : {
121 4 : rc = assuan_register_command (ctx, table[i].name, table[i].handler, NULL);
122 4 : if (rc)
123 0 : return rc;
124 : }
125 1 : return 0;
126 : }
127 :
128 :
129 : static void
130 1 : run_server (int enable_debug)
131 : {
132 : int rc;
133 : assuan_context_t ctx;
134 : assuan_fd_t filedes[2];
135 :
136 1 : filedes[0] = my_stdin;
137 1 : filedes[1] = my_stdout;
138 :
139 1 : rc = assuan_new (&ctx);
140 1 : if (rc)
141 0 : log_fatal ("assuan_new failed: %s\n", gpg_strerror (rc));
142 :
143 1 : rc = assuan_init_pipe_server (ctx, filedes);
144 1 : if (rc)
145 0 : log_fatal ("assuan_init_pipe_server failed: %s\n",
146 : gpg_strerror (rc));
147 :
148 1 : rc = server_register_commands (ctx);
149 1 : if (rc)
150 0 : log_fatal ("register_commands failed: %s\n", gpg_strerror(rc));
151 :
152 1 : if (enable_debug)
153 0 : assuan_set_log_stream (ctx, stderr);
154 :
155 : for (;;)
156 : {
157 3 : rc = assuan_accept (ctx);
158 2 : if (rc)
159 : {
160 1 : if (rc != -1)
161 0 : log_error ("assuan_accept failed: %s\n", gpg_strerror (rc));
162 1 : break;
163 : }
164 :
165 1 : log_info ("client connected. Client's pid is %ld\n",
166 1 : (long)assuan_get_pid (ctx));
167 :
168 1 : rc = assuan_process (ctx);
169 1 : if (rc)
170 0 : log_error ("assuan_process failed: %s\n", gpg_strerror (rc));
171 : }
172 :
173 1 : assuan_release (ctx);
174 1 : }
175 :
176 :
177 :
178 :
179 :
180 :
181 :
182 : static gpg_error_t
183 1 : data_cb (void *opaque, const void *buffer, size_t length)
184 : {
185 : (void)opaque;
186 :
187 1 : if (buffer)
188 1 : printf ("Received data `%.*s'\n", (int)length, (char*)buffer);
189 1 : return 0;
190 : }
191 :
192 :
193 : static void
194 1 : run_client (const char *servername)
195 : {
196 : gpg_error_t err;
197 : assuan_context_t ctx;
198 : assuan_fd_t no_close_fds[2];
199 : const char *arglist[5];
200 :
201 1 : no_close_fds[0] = fileno (stderr);
202 1 : no_close_fds[1] = ASSUAN_INVALID_FD;
203 :
204 1 : arglist[0] = servername;
205 1 : arglist[1] = "--server";
206 1 : arglist[2] = debug? "--debug" : verbose? "--verbose":NULL;
207 1 : arglist[3] = NULL;
208 :
209 1 : err = assuan_new (&ctx);
210 1 : if (err)
211 0 : log_fatal ("assuan_new failed: %s\n", gpg_strerror (err));
212 :
213 1 : err = assuan_pipe_connect (ctx, servername, arglist, no_close_fds,
214 : NULL, NULL, 0);
215 1 : if (err)
216 : {
217 0 : log_error ("assuan_pipe_connect failed: %s\n",
218 : gpg_strerror (err));
219 0 : assuan_release (ctx);
220 0 : return;
221 : }
222 :
223 1 : log_info ("server started; pid is %ld\n",
224 1 : (long)assuan_get_pid (ctx));
225 :
226 1 : err = assuan_transact (ctx, "ECHO Your lucky number is 3552664958674928. "
227 : "Watch for it everywhere.",
228 : data_cb, NULL, NULL, NULL, NULL, NULL);
229 1 : if (err)
230 : {
231 0 : log_error ("sending ECHO failed: %s\n", gpg_strerror (err));
232 0 : return;
233 : }
234 :
235 1 : err = assuan_transact (ctx, "BYE", NULL, NULL, NULL, NULL, NULL, NULL);
236 1 : if (err)
237 : {
238 0 : log_error ("sending BYE failed: %s\n", gpg_strerror (err));
239 0 : return;
240 : }
241 :
242 1 : assuan_release (ctx);
243 1 : return;
244 : }
245 :
246 :
247 : static void
248 2 : parse_std_file_handles (int *argcp, char ***argvp)
249 : {
250 : #ifdef HAVE_W32CE_SYSTEM
251 : int argc = *argcp;
252 : char **argv = *argvp;
253 : const char *s;
254 : assuan_fd_t fd;
255 : int i;
256 : int fixup = 0;
257 :
258 : if (!argc)
259 : return;
260 :
261 : for (argc--, argv++; argc; argc--, argv++)
262 : {
263 : s = *argv;
264 : if (*s == '-' && s[1] == '&' && s[2] == 'S'
265 : && (s[3] == '0' || s[3] == '1' || s[3] == '2')
266 : && s[4] == '='
267 : && (strchr ("-01234567890", s[5]) || !strcmp (s+5, "null")))
268 : {
269 : if (s[5] == 'n')
270 : fd = ASSUAN_INVALID_FD;
271 : else
272 : fd = _assuan_w32ce_finish_pipe (atoi (s+5), s[3] != '0');
273 : switch (s[3] - '0')
274 : {
275 : case 0: my_stdin = fd; break;
276 : case 1: my_stdout = fd; break;
277 : case 2: my_stderr = fd; break;
278 : }
279 :
280 : fixup++;
281 : }
282 : else
283 : break;
284 : }
285 :
286 : if (fixup)
287 : {
288 : argc = *argcp;
289 : argc -= fixup;
290 : *argcp = argc;
291 :
292 : argv = *argvp;
293 : for (i=1; i < argc; i++)
294 : argv[i] = argv[i + fixup];
295 : for (; i < argc + fixup; i++)
296 : argv[i] = NULL;
297 : }
298 : #else
299 : (void)argcp;
300 : (void)argvp;
301 2 : my_stdin = 0;
302 2 : my_stdout = 1;
303 2 : my_stderr = 2;
304 : #endif
305 2 : }
306 :
307 :
308 : /*
309 : M A I N
310 : */
311 : int
312 2 : main (int argc, char **argv)
313 : {
314 : gpg_error_t err;
315 2 : const char *myname = "no-pgm";
316 2 : int last_argc = -1;
317 2 : int server = 0;
318 2 : int silent_client = 0;
319 2 : int silent_server = 0;
320 :
321 2 : parse_std_file_handles (&argc, &argv);
322 2 : if (argc)
323 : {
324 2 : myname = *argv;
325 2 : log_set_prefix (*argv);
326 2 : argc--; argv++;
327 : }
328 5 : while (argc && last_argc != argc )
329 : {
330 1 : last_argc = argc;
331 1 : if (!strcmp (*argv, "--help"))
332 : {
333 0 : printf ("usage: %s [options]\n"
334 : "\n"
335 : "Options:\n"
336 : " --verbose Show what is going on\n"
337 : " --server Run in server mode\n",
338 : log_get_prefix ());
339 0 : exit (0);
340 : }
341 1 : if (!strcmp (*argv, "--verbose"))
342 : {
343 0 : verbose = 1;
344 0 : argc--; argv++;
345 : }
346 1 : else if (!strcmp (*argv, "--debug"))
347 : {
348 0 : verbose = debug = 1;
349 0 : argc--; argv++;
350 : }
351 1 : else if (!strcmp (*argv, "--server"))
352 : {
353 1 : server = 1;
354 1 : argc--; argv++;
355 : }
356 0 : else if (!strcmp (*argv, "--silent-server"))
357 : {
358 0 : silent_server = 1;
359 0 : argc--; argv++;
360 : }
361 0 : else if (!strcmp (*argv, "--silent-client"))
362 : {
363 0 : silent_client = 1;
364 0 : argc--; argv++;
365 : }
366 : else
367 0 : log_fatal ("invalid option `%s' (try --help)\n", *argv);
368 : }
369 :
370 2 : log_set_prefix (xstrconcat (log_get_prefix (),
371 : server? ".server":".client", NULL));
372 2 : assuan_set_assuan_log_prefix (log_get_prefix ());
373 :
374 2 : err = assuan_sock_init ();
375 2 : if (err)
376 0 : log_fatal ("socket init failed: %s\n", gpg_strerror (err));
377 :
378 2 : if (server)
379 : {
380 1 : log_info ("server started\n");
381 1 : if (debug && !silent_server)
382 0 : assuan_set_assuan_log_stream (stderr);
383 1 : run_server (debug && !silent_server);
384 1 : log_info ("server finished\n");
385 : }
386 : else
387 : {
388 1 : log_info ("client started\n");
389 1 : if (debug && !silent_client)
390 0 : assuan_set_assuan_log_stream (stderr);
391 1 : run_client (myname);
392 1 : log_info ("client finished\n");
393 : }
394 :
395 2 : return errorcount ? 1 : 0;
396 : }
397 :
|