Line data Source code
1 : /* assuan-pipe-server.c - Assuan server working over a pipe
2 : Copyright (C) 2001, 2002, 2009 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 2.1 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 : #ifdef HAVE_CONFIG_H
21 : #include <config.h>
22 : #endif
23 :
24 : #include <stdlib.h>
25 : #include <stdio.h>
26 : #ifdef HAVE_SYS_TYPES_H
27 : # include <sys/types.h>
28 : #endif
29 : #ifdef HAVE_SYS_STAT_H
30 : # include <sys/stat.h>
31 : #endif
32 : #ifdef HAVE_UNISTD_H
33 : # include <unistd.h>
34 : #endif
35 : #ifdef HAVE_W32_SYSTEM
36 : # ifdef HAVE_WINSOCK2_H
37 : # include <winsock2.h>
38 : # endif
39 : # include <windows.h>
40 : #ifdef HAVE_FCNTL_H
41 : # include <fcntl.h>
42 : #endif
43 : #endif
44 :
45 : #include "assuan-defs.h"
46 : #include "debug.h"
47 :
48 : /* Returns true if atoi(S) denotes a valid socket. */
49 : #ifndef HAVE_W32_SYSTEM
50 : static int
51 1 : is_valid_socket (const char *s)
52 : {
53 : struct stat buf;
54 :
55 1 : if ( fstat (atoi (s), &buf ) )
56 0 : return 0;
57 1 : return S_ISSOCK (buf.st_mode);
58 : }
59 : #endif /*!HAVE_W32_SYSTEM*/
60 :
61 :
62 : /* This actually is a int file descriptor (and not assuan_fd_t) as
63 : _get_osfhandle is called on W32 systems. */
64 : gpg_error_t
65 2 : assuan_init_pipe_server (assuan_context_t ctx, assuan_fd_t filedes[2])
66 : {
67 : const char *s;
68 : unsigned long ul;
69 : gpg_error_t rc;
70 2 : assuan_fd_t infd = ASSUAN_INVALID_FD;
71 2 : assuan_fd_t outfd = ASSUAN_INVALID_FD;
72 2 : int is_usd = 0;
73 2 : TRACE_BEG (ctx, ASSUAN_LOG_CTX, "assuan_init_pipe_server", ctx);
74 2 : if (filedes)
75 : {
76 1 : TRACE_LOG2 ("fd[0]=0x%x, fd[1]=0x%x", filedes[0], filedes[1]);
77 : }
78 :
79 2 : rc = _assuan_register_std_commands (ctx);
80 2 : if (rc)
81 0 : return TRACE_ERR (rc);
82 :
83 : #ifdef HAVE_W32_SYSTEM
84 : infd = filedes[0];
85 : outfd = filedes[1];
86 : #else
87 2 : s = getenv ("_assuan_connection_fd");
88 2 : if (s && *s && is_valid_socket (s))
89 : {
90 : /* Well, we are called with an bi-directional file descriptor.
91 : Prepare for using sendmsg/recvmsg. In this case we ignore
92 : the passed file descriptors. */
93 1 : infd = atoi (s);
94 1 : outfd = atoi (s);
95 1 : is_usd = 1;
96 :
97 : }
98 1 : else if (filedes && filedes[0] != ASSUAN_INVALID_FD
99 1 : && filedes[1] != ASSUAN_INVALID_FD )
100 : {
101 : /* Standard pipe server. */
102 1 : infd = filedes[0];
103 1 : outfd = filedes[1];
104 : }
105 : else
106 : {
107 0 : rc = _assuan_error (ctx, GPG_ERR_ASS_SERVER_START);
108 0 : return TRACE_ERR (rc);
109 : }
110 : #endif
111 :
112 2 : ctx->is_server = 1;
113 2 : ctx->engine.release = _assuan_server_release;
114 2 : ctx->engine.readfnc = _assuan_simple_read;
115 2 : ctx->engine.writefnc = _assuan_simple_write;
116 2 : ctx->engine.sendfd = NULL;
117 2 : ctx->engine.receivefd = NULL;
118 2 : ctx->max_accepts = 1;
119 :
120 2 : s = getenv ("_assuan_pipe_connect_pid");
121 2 : if (s && (ul=strtoul (s, NULL, 10)) && ul)
122 2 : ctx->pid = (pid_t)ul;
123 : else
124 0 : ctx->pid = (pid_t)-1;
125 2 : ctx->accept_handler = NULL;
126 2 : ctx->finish_handler = _assuan_server_finish;
127 2 : ctx->inbound.fd = infd;
128 2 : ctx->outbound.fd = outfd;
129 :
130 2 : if (is_usd)
131 1 : _assuan_init_uds_io (ctx);
132 :
133 2 : return TRACE_SUC();
134 : }
|