Line data Source code
1 : /* assuan-listen.c - Wait for a connection (server)
2 : Copyright (C) 2001, 2002, 2004, 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 : #include <string.h>
27 : #ifdef HAVE_UNISTD_H
28 : # include <unistd.h>
29 : #endif
30 : #include <errno.h>
31 :
32 : #include "assuan-defs.h"
33 :
34 : gpg_error_t
35 0 : assuan_set_hello_line (assuan_context_t ctx, const char *line)
36 : {
37 0 : if (!ctx)
38 0 : return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
39 0 : if (!line)
40 : {
41 0 : _assuan_free (ctx, ctx->hello_line);
42 0 : ctx->hello_line = NULL;
43 : }
44 : else
45 : {
46 0 : char *buf = _assuan_malloc (ctx, 3 + strlen (line) + 1);
47 0 : if (!buf)
48 0 : return _assuan_error (ctx, gpg_err_code_from_syserror ());
49 0 : if (strchr (line, '\n'))
50 0 : strcpy (buf, line);
51 : else
52 : {
53 0 : strcpy (buf, "OK ");
54 0 : strcpy (buf+3, line);
55 : }
56 0 : _assuan_free (ctx, ctx->hello_line);
57 0 : ctx->hello_line = buf;
58 : }
59 0 : return 0;
60 : }
61 :
62 :
63 : /**
64 : * assuan_accept:
65 : * @ctx: context
66 : *
67 : * Cancel any existing connection and wait for a connection from a
68 : * client. The initial handshake is performed which may include an
69 : * initial authentication or encryption negotiation.
70 : *
71 : * Return value: 0 on success or an error if the connection could for
72 : * some reason not be established.
73 : **/
74 : gpg_error_t
75 4 : assuan_accept (assuan_context_t ctx)
76 : {
77 4 : gpg_error_t rc = 0;
78 : const char *p, *pend;
79 :
80 4 : if (!ctx)
81 0 : return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
82 :
83 4 : if (ctx->max_accepts != -1)
84 : {
85 4 : if (ctx->max_accepts-- == 0)
86 2 : return -1; /* second invocation for pipemode -> terminate */
87 : }
88 2 : if (ctx->accept_handler)
89 : {
90 : /* FIXME: This should be superfluous, if everything else is
91 : correct. */
92 0 : ctx->finish_handler (ctx);
93 0 : rc = ctx->accept_handler (ctx);
94 0 : if (rc)
95 0 : return rc;
96 : }
97 :
98 : /* Send the hello. */
99 2 : p = ctx->hello_line;
100 2 : if (p && (pend = strchr (p, '\n')))
101 : { /* This is a multi line hello. Send all but the last line as
102 : comments. */
103 : do
104 : {
105 0 : rc = _assuan_write_line (ctx, "# ", p, pend - p);
106 0 : if (rc)
107 0 : return rc;
108 0 : p = pend + 1;
109 0 : pend = strchr (p, '\n');
110 : }
111 0 : while (pend);
112 0 : rc = _assuan_write_line (ctx, "OK ", p, strlen (p));
113 : }
114 2 : else if (p)
115 0 : rc = assuan_write_line (ctx, p);
116 : else
117 : {
118 : static char const okstr[] = "OK Pleased to meet you";
119 2 : pid_t apid = assuan_get_pid (ctx);
120 2 : if (apid != ASSUAN_INVALID_PID)
121 : {
122 : char tmpbuf[50];
123 2 : snprintf (tmpbuf, sizeof tmpbuf, "%s, process %i", okstr, (int)apid);
124 2 : rc = assuan_write_line (ctx, tmpbuf);
125 : }
126 : else
127 0 : rc = assuan_write_line (ctx, okstr);
128 : }
129 2 : if (rc)
130 0 : return rc;
131 :
132 2 : return 0;
133 : }
134 :
135 :
136 :
137 : assuan_fd_t
138 6 : assuan_get_input_fd (assuan_context_t ctx)
139 : {
140 6 : return ctx ? ctx->input_fd : ASSUAN_INVALID_FD;
141 : }
142 :
143 :
144 : assuan_fd_t
145 0 : assuan_get_output_fd (assuan_context_t ctx)
146 : {
147 0 : return ctx ? ctx->output_fd : ASSUAN_INVALID_FD;
148 : }
149 :
150 :
151 : /* Close the fd descriptor set by the command INPUT FD=n. We handle
152 : this fd inside assuan so that we can do some initial checks */
153 : gpg_error_t
154 2 : assuan_close_input_fd (assuan_context_t ctx)
155 : {
156 2 : if (!ctx || ctx->input_fd == ASSUAN_INVALID_FD)
157 1 : return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
158 1 : _assuan_close (ctx, ctx->input_fd);
159 1 : ctx->input_fd = ASSUAN_INVALID_FD;
160 1 : return 0;
161 : }
162 :
163 : /* Close the fd descriptor set by the command OUTPUT FD=n. We handle
164 : this fd inside assuan so that we can do some initial checks */
165 : gpg_error_t
166 2 : assuan_close_output_fd (assuan_context_t ctx)
167 : {
168 2 : if (!ctx || ctx->output_fd == ASSUAN_INVALID_FD)
169 2 : return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
170 :
171 0 : _assuan_close (ctx, ctx->output_fd);
172 0 : ctx->output_fd = ASSUAN_INVALID_FD;
173 0 : return 0;
174 : }
175 :
|