181 #define STR(x) vstring_str(x)
182 #define LEN(x) VSTRING_LEN(x)
186 static int attr_scan_plain_string(
VSTREAM *fp,
VSTRING *plain_buf,
187 int terminator,
const char *context)
191 int limit = var_line_limit * 4;
198 && (terminator == 0 || ch != terminator)) {
200 msg_warn(
"%s on %s while reading %s",
207 if (
LEN(plain_buf) > limit) {
208 msg_warn(
"string length > %d characters from %s while reading %s",
217 msg_info(
"%s: %s", context, *
STR(plain_buf) ?
STR(plain_buf) :
"(end)");
227 static VSTRING *base64_buf = 0;
232 if ((ch = attr_scan_plain_string(fp, base64_buf, terminator, context)) < 0)
235 msg_warn(
"malformed base64 data from %s while reading %s: %.100s",
244 static int attr_scan_plain_number(
VSTREAM *fp,
unsigned *ptr,
VSTRING *str_buf,
245 int terminator,
const char *context)
250 if ((ch = attr_scan_plain_string(fp, str_buf, terminator, context)) < 0)
252 if (sscanf(
STR(str_buf),
"%u%c", ptr, &junk) != 1 || junk != 0) {
253 msg_warn(
"malformed numerical data from %s while reading %s: %.100s",
262 static int attr_scan_plain_long_number(
VSTREAM *fp,
unsigned long *ptr,
270 if ((ch = attr_scan_plain_string(fp, str_buf, terminator, context)) < 0)
272 if (sscanf(
STR(str_buf),
"%lu%c", ptr, &junk) != 1 || junk != 0) {
273 msg_warn(
"malformed numerical data from %s while reading %s: %.100s",
284 const char *myname =
"attr_scan_plain";
287 int wanted_type = -1;
289 unsigned int *number;
290 unsigned long *long_number;
302 msg_panic(
"%s: bad flags: 0x%x", myname, flags);
322 for (conversions = 0; ; conversions++) {
335 wanted_type = va_arg(ap,
int);
338 return (conversions);
339 wanted_name =
"(list terminator)";
341 wanted_name =
"(any attribute name or list terminator)";
342 hash_table = va_arg(ap,
HTABLE *);
344 wanted_name = va_arg(ap,
char *);
359 msg_info(
"%s: wanted attribute: %s",
361 if ((ch = attr_scan_plain_string(fp, name_buf,
'=',
364 if (ch ==
'\n' &&
LEN(name_buf) == 0) {
367 return (conversions);
369 msg_warn(
"missing attribute %s in input from %s",
371 return (conversions);
380 wanted_name =
"(any attribute name or '}')";
392 && strcmp(wanted_name,
STR(name_buf)) == 0))
395 msg_warn(
"unexpected attribute %s from %s (expecting: %s)",
397 return (conversions);
410 switch (wanted_type) {
413 msg_warn(
"missing value for number attribute %s from %s",
417 number = va_arg(ap,
unsigned int *);
418 if ((ch = attr_scan_plain_number(fp, number, str_buf, 0,
419 "input attribute value")) < 0)
424 msg_warn(
"missing value for number attribute %s from %s",
428 long_number = va_arg(ap,
unsigned long *);
429 if ((ch = attr_scan_plain_long_number(fp, long_number, str_buf,
430 0,
"input attribute value")) < 0)
435 msg_warn(
"missing value for string attribute %s from %s",
439 string = va_arg(ap,
VSTRING *);
440 if ((ch = attr_scan_plain_string(fp,
string, 0,
441 "input attribute value")) < 0)
446 msg_warn(
"missing value for data attribute %s from %s",
450 string = va_arg(ap,
VSTRING *);
451 if ((ch = attr_scan_plain_data(fp,
string, 0,
452 "input attribute value")) < 0)
457 scan_arg = va_arg(ap,
void *);
464 msg_warn(
"missing value for string attribute %s from %s",
468 if ((ch = attr_scan_plain_string(fp, str_buf, 0,
469 "input attribute value")) < 0)
473 msg_warn(
"duplicate attribute %s in input from %s",
475 return (conversions);
478 msg_warn(
"attribute count exceeds limit %d in input from %s",
480 return (conversions);
490 msg_panic(
"%s: unknown type code: %d", myname, wanted_type);
525 msg_info(
"%s: non-terminator '%c' (lookahead)",
542 int main(
int unused_argc,
char **used_argv)
570 for (ht = ht_info_list; *ht; ht++)
571 vstream_printf(
"(hash) %s %s\n", ht[0]->key, (
char *) ht[0]->value);
572 myfree((
void *) ht_info_list);
589 for (ht = ht_info_list; *ht; ht++)
590 vstream_printf(
"(hash) %s %s\n", ht[0]->key, (
char *) ht[0]->value);
591 myfree((
void *) ht_info_list);
void htable_free(HTABLE *table, void(*free_fn)(void *))
HTABLE_INFO * htable_locate(HTABLE *table, const char *key)
int attr_scan_more_plain(VSTREAM *fp)
char * mystrdup(const char *str)
NORETURN msg_panic(const char *fmt,...)
#define ATTR_FLAG_MISSING
int main(int argc, char **argv)
int attr_vscan_plain(VSTREAM *fp, int flags, va_list ap)
#define RECV_ATTR_INT(name, val)
#define RECV_ATTR_HASH(val)
int attr_scan_plain(VSTREAM *fp, int flags,...)
#define VSTRING_TERMINATE(vp)
HTABLE * htable_create(ssize_t size)
#define VSTRING_ADDCH(vp, ch)
HTABLE_INFO ** htable_list(HTABLE *table)
#define vstream_ungetc(vp, ch)
#define vstream_ftimeout(vp)
#define RECV_ATTR_LONG(name, val)
VSTREAM * vstream_printf(const char *fmt,...)
#define VSTRING_RESET(vp)
void msg_warn(const char *fmt,...)
#define RECV_ATTR_DATA(name, val)
VSTRING * vstring_alloc(ssize_t len)
NORETURN msg_fatal(const char *fmt,...)
VSTRING * base64_decode(VSTRING *, const char *, ssize_t)
int vstream_fflush(VSTREAM *stream)
VSTRING * vstring_free(VSTRING *vp)
void msg_vstream_init(const char *name, VSTREAM *vp)
int(* ATTR_SCAN_SLAVE_FN)(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *)
#define RECV_ATTR_STR(name, val)
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
void msg_info(const char *fmt,...)