src/daemon/logging.c \
src/daemon/logging.h \
src/daemon/main.c \
+ src/daemon/parse.c \
+ src/daemon/parse.h \
src/daemon/proc.c \
src/daemon/proc.h \
src/daemon/proto.c \
--- /dev/null
+/*#############################################################################
+# #
+# collecty - A system statistics collection daemon for IPFire #
+# Copyright (C) 2025 IPFire Development Team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <ctype.h>
+
+#include "parse.h"
+#include "string.h"
+
+static void collecty_skip_whitespace(char** s) {
+ char* p = *s;
+
+ // Consume any whitespace
+ while (*p && isspace(*p))
+ p++;
+
+ // Reset s
+ *s = p;
+}
+
+int __collecty_parse_token(char** line, char* token, size_t length) {
+ char* p = *line;
+ int r;
+
+ // Skip any leading whitespace
+ collecty_skip_whitespace(&p);
+
+ // End of line
+ if (!*p)
+ return __collecty_string_set(token, length, "");
+
+ // Pointer that points to the end of the token
+ char* e = p;
+
+ // Advance the end pointer until we hit some whitespace
+ while (*e && !isspace(*e))
+ e++;
+
+ // Copy the token
+ r = __collecty_string_setn(token, length, p, e - p);
+ if (r < 0)
+ return r;
+
+ // Reset line
+ *line = e;
+ return 0;
+}
+
+int collecty_parse_uint64(char** line, uint64_t* value) {
+ char* p = *line;
+ char* e = NULL;
+
+ // Skip any leading whitespace
+ collecty_skip_whitespace(&p);
+
+ // Parse the value
+ *value = strtoul(p, &e, 10);
+
+ // Assume that parsing failed if the next character is not whitespace
+ if (*e && !isspace(*e))
+ return -EINVAL;
+
+ // Reset line
+ *line = e;
+ return 0;
+}
--- /dev/null
+/*#############################################################################
+# #
+# collecty - A system statistics collection daemon for IPFire #
+# Copyright (C) 2025 IPFire Development Team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef COLLECTY_PARSE_H
+#define COLLECTY_PARSE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define collecty_parse_token(line, token) \
+ __collecty_parse_token(line, token, sizeof(token))
+
+int __collecty_parse_token(char** line, char* token, size_t length);
+
+int collecty_parse_uint64(char** line, uint64_t* value);
+
+#endif /* COLLECTY_PARSE_H */
#include <string.h>
#include "file.h"
+#include "parse.h"
#include "proc.h"
#include "string.h"
static int collecty_proc_softirq_line(collecty_ctx* ctx,
unsigned long lineno, char* line, size_t length, void* data) {
collecty_proc_softirq_state* state = data;
- char* e = NULL;
- char* p = NULL;
- char* t = NULL;
+ uint64_t n = 0;
uint64_t v = 0;
char key[16];
int r;
if (!lineno++)
return 0;
- // Fetch the key
- t = strtok_r(line, ":", &p);
- if (!t)
- return -errno;
-
- // Store the key
- r = collecty_string_set(key, t);
+ // Parse the key
+ r = collecty_parse_token(&line, key);
if (r < 0)
- return -errno;
+ return r;
- // Strip any whitespace
- collecty_string_strip(key);
+ // Remove the trailing :
+ collecty_string_rstrip2(key, ':');
// Add up all values
- for (;;) {
- // Fetch the next token
- t = strtok_r(NULL, " ", &p);
- if (!t)
- break;
-
- // Parse the token
- v += strtoul(t, &e, 10);
-
- // Check if could parse the value
- switch (*e) {
- case '\0':
- case '\n':
- break;
+ while (*line) {
+ r = collecty_parse_uint64(&line, &v);
+ if (r < 0)
+ return r;
- default:
- return -EINVAL;
- }
+ // Sum up all values
+ n += v;
}
// Call the callback
- return state->callback(ctx, key, v, state->data);
+ return state->callback(ctx, key, n, state->data);
}
int collecty_proc_read_softirq(collecty_ctx* ctx,