1 /* assuan-client.c - client functions
2 * Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
4 * This file is part of Assuan.
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.
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.
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/>.
27 #include "assuan-defs.h"
29 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
30 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
31 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
35 _assuan_read_from_server (assuan_context_t ctx
, int *okay
, int *off
)
47 rc
= _assuan_read_line (ctx
);
49 while (_assuan_error_is_eagain (rc
) && !ctx
->in_inquire
);
52 line
= ctx
->inbound
.line
;
53 linelen
= ctx
->inbound
.linelen
;
55 while (*line
== '#' || !linelen
);
58 && line
[0] == 'D' && line
[1] == ' ')
60 *okay
= 2; /* data line */
65 && (line
[1] == '\0' || line
[1] == ' '))
69 while (line
[*off
] == ' ')
73 && line
[0] == 'O' && line
[1] == 'K'
74 && (line
[2] == '\0' || line
[2] == ' '))
78 while (line
[*off
] == ' ')
82 && line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R'
83 && (line
[3] == '\0' || line
[3] == ' '))
87 while (line
[*off
] == ' ')
91 && line
[0] == 'I' && line
[1] == 'N' && line
[2] == 'Q'
92 && line
[3] == 'U' && line
[4] == 'I' && line
[5] == 'R'
94 && (line
[7] == '\0' || line
[7] == ' '))
99 while (line
[*off
] == ' ')
102 else if (linelen
>= 3
103 && line
[0] == 'E' && line
[1] == 'N' && line
[2] == 'D'
104 && (line
[3] == '\0' || line
[3] == ' '))
106 *okay
= 5; /* end line */
110 rc
= _assuan_error (ASSUAN_Invalid_Response
);
118 * @ctx: The Assuan context
119 * @command: Command line to be send to the server
120 * @data_cb: Callback function for data lines
121 * @data_cb_arg: first argument passed to @data_cb
122 * @inquire_cb: Callback function for a inquire response
123 * @inquire_cb_arg: first argument passed to @inquire_cb
124 * @status_cb: Callback function for a status response
125 * @status_cb_arg: first argument passed to @status_cb
127 * FIXME: Write documentation
129 * Return value: 0 on success or error code. The error code may be
130 * the one one returned by the server in error lines or from the
131 * callback functions. Take care: When a callback returns an error
132 * this function returns immediately with an error and thus the caller
133 * will altter return an Assuan error (write erro in most cases).
136 assuan_transact (assuan_context_t ctx
,
138 int (*data_cb
)(void *, const void *, size_t),
140 int (*inquire_cb
)(void*, const char *),
141 void *inquire_cb_arg
,
142 int (*status_cb
)(void*, const char *),
151 rc
= assuan_write_line (ctx
, command
);
155 if (*command
== '#' || !*command
)
156 return 0; /* Don't expect a response for a comment line. */
159 rc
= _assuan_read_from_server (ctx
, &okay
, &off
);
161 return rc
; /* error reading from server */
163 line
= ctx
->inbound
.line
+ off
;
164 linelen
= ctx
->inbound
.linelen
- off
;
169 if (rc
> 0 && rc
< 100)
170 rc
= _assuan_error (ASSUAN_Server_Fault
);
171 else if (rc
> 0 && rc
<= 405)
172 rc
= _assuan_error (rc
);
177 rc
= _assuan_error (ASSUAN_No_Data_Callback
);
182 for (s
=d
=line
; linelen
; linelen
--)
184 if (*s
== '%' && linelen
> 2)
185 { /* handle escaping */
194 *d
= 0; /* add a hidden string terminator */
195 rc
= data_cb (data_cb_arg
, line
, d
- line
);
204 assuan_write_line (ctx
, "END"); /* get out of inquire mode */
205 _assuan_read_from_server (ctx
, &okay
, &off
); /* dummy read */
206 rc
= _assuan_error (ASSUAN_No_Inquire_Callback
);
210 rc
= inquire_cb (inquire_cb_arg
, line
);
213 rc
= assuan_send_data (ctx
, NULL
, 0); /* flush and send END */
221 rc
= status_cb (status_cb_arg
, line
);
228 rc
= _assuan_error (ASSUAN_No_Data_Callback
);
231 rc
= data_cb (data_cb_arg
, NULL
, 0);