1
/* assuan-inquire.c - handle inquire stuff
2
* Copyright (C) 2001, 2002 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, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
26
#include "assuan-defs.h"
28
#define digitp(a) ((a) >= '0' && (a) <= '9')
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))
45
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
46
create a buffer, put_membuf to append bytes and get_membuf to
47
release and return the buffer. Allocation errors are detected but
48
only returned at the final get_membuf(), this helps not to clutter
49
the code with out of core checks. */
52
init_membuf (struct membuf *mb, int initiallen, size_t maxlen)
55
mb->size = initiallen;
59
/* we need to allocate one byte more for get_membuf */
60
mb->buf = xtrymalloc (initiallen+1);
66
put_membuf (struct membuf *mb, const void *buf, size_t len)
68
if (mb->out_of_core || mb->too_large)
71
if (mb->maxlen && mb->len + len > mb->maxlen)
77
if (mb->len + len >= mb->size)
81
mb->size += len + 1024;
82
/* we need to allocate one byte more for get_membuf */
83
p = xtryrealloc (mb->buf, mb->size+1);
91
memcpy (mb->buf + mb->len, buf, len);
96
get_membuf (struct membuf *mb, size_t *len)
100
if (mb->out_of_core || mb->too_large)
107
mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */
111
mb->out_of_core = 1; /* don't allow a reuse */
116
free_membuf (struct membuf *mb)
125
* @ctx: An assuan context
126
* @keyword: The keyword used for the inquire
127
* @r_buffer: Returns an allocated buffer
128
* @r_length: Returns the length of this buffer
129
* @maxlen: If not 0, the size limit of the inquired data.
131
* A Server may use this to Send an inquire. r_buffer, r_length and
132
* maxlen may all be NULL/0 to indicate that no real data is expected.
134
* Return value: 0 on success or an ASSUAN error code
137
assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
138
char **r_buffer, size_t *r_length, size_t maxlen)
143
unsigned char *line, *p;
147
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
148
return ASSUAN_Invalid_Value;
149
nodataexpected = !r_buffer && !r_length && !maxlen;
150
if (!nodataexpected && (!r_buffer || !r_length))
151
return ASSUAN_Invalid_Value;
153
return ASSUAN_Not_A_Server;
155
return ASSUAN_Nested_Commands;
159
memset (&mb, 0, sizeof mb); /* avoid compiler warnings */
161
init_membuf (&mb, maxlen? maxlen:1024, maxlen);
163
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
164
rc = assuan_write_line (ctx, cmdbuf);
172
rc = _assuan_read_line (ctx);
175
line = ctx->inbound.line;
176
linelen = ctx->inbound.linelen;
178
while (*line == '#' || !linelen);
179
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
180
&& (!line[3] || line[3] == ' '))
181
break; /* END command received*/
182
if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
184
rc = ASSUAN_Canceled;
187
if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
189
rc = ASSUAN_Unexpected_Command;
200
for (;linelen && *p != '%'; linelen--, p++)
202
put_membuf (&mb, line, p-line);
204
{ /* handle escaping */
205
unsigned char tmp[1];
210
put_membuf (&mb, tmp, 1);
216
rc = ASSUAN_Too_Much_Data;
223
*r_buffer = get_membuf (&mb, r_length);
225
rc = ASSUAN_Out_Of_Core;