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