command.c: Document return value of handle_connect().
[paraslash.git] / stat.c
1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /**
4 * \file stat.c Functions used for sending/receiving the status of para_server
5 * and para_audiod.
6 */
7
8 #include <regex.h>
9
10 #include "para.h"
11 #include "error.h"
12 #include "string.h"
13
14
15 /** The minimal length of a status item buffer. */
16 #define MIN_STAT_ITEM_LEN 9 /* 5 + 2 + 2, e.g. '0005 00:\n' */
17
18 /**
19 * Call a function for each complete status item of a buffer.
20 *
21 * \param item_buf The source buffer.
22 * \param num_bytes The length of \a buf.
23 * \param item_handler Function to call for each complete item.
24 *
25 * \return Negative on errors, the number of bytes _not_ passed to \a
26 * item_handler on success.
27 *
28 * Status items are expected in the format used by parser-friendly output mode
29 * of the stat command of para_client/para_audioc.
30 */
31 int for_each_stat_item(char *item_buf, size_t num_bytes,
32 int (*item_handler)(int, char *))
33 {
34 char *buf = item_buf;
35 int len = num_bytes;
36
37 for (;;) {
38 int i, ret, item_len, item_num = 0;
39 if (len < MIN_STAT_ITEM_LEN)
40 break;
41 ret = read_size_header(buf);
42 if (ret < 0)
43 return ret;
44 item_len = ret;
45 if (item_len > len - 5) /* item not complete */
46 break;
47 for (i = 0; i < 2; i++) {
48 unsigned char c = buf[5 + i];
49 item_num <<= 4;
50 if (c >= '0' && c <= '9') {
51 item_num += c - '0';
52 continue;
53 }
54 if (c >= 'a' && c <= 'f') {
55 item_num += c - 'a' + 10;
56 continue;
57 }
58 return -E_STAT_ITEM_PARSE;
59 }
60 if (buf[7] != ':' || buf[5 + item_len - 1] != '\n')
61 return -E_STAT_ITEM_PARSE;
62 buf[5 + item_len - 1] = '\0';
63 if (item_num >= NUM_STAT_ITEMS)
64 PARA_WARNING_LOG("unknown status item %d: %s\n",
65 item_num, buf + 8);
66 else {
67 ret = item_handler(item_num, buf + 8);
68 if (ret < 0)
69 return ret;
70 }
71 buf += 5 + item_len;
72 len -= 5 + item_len;
73 assert(len >= 0 && buf <= item_buf + num_bytes);
74 }
75 assert(len >= 0);
76 return len;
77 }