0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "macro.h"
8 #include "strlcpy.h"
9 #include "error.h"
10 #define CONFIG_INTERNAL
11 #include "config.h"
12 #define ABOUT_INTERNAL
13 #include "about.h"
14
15 int about_config_arg(char *param, char **out, size_t *length_out) {
16 int id, len;
17 size_t length = 0;
18 char *data;
19 char *query = strchr(param, '?');
20 char buf[1024];
21 if (query) {
22 *query = '\0';
23 query++;
24 }
25 id = atoi(param);
26 if ((!id && strcmp(param, "0")) || (unsigned)id > LENGTH(fields)) {
27 return ERROR_INVALID_ARGUMENT;
28 }
29 if (query) {
30 int ret = config_set_field(id, query);
31 if (ret) return ret;
32 return about_config(out, length_out);
33 }
34 len = snprintf(V(buf), "10 %s\r\n0", fields[id].name);
35 if (!(data = dyn_strcat(NULL, &length, buf, len)))
36 return ERROR_MEMORY_FAILURE;
37 *out = data;
38 *length_out = length;
39 return 0;
40 }
41
42 int about_config(char **out, size_t *length_out) {
43
44 size_t length = 0;
45 unsigned int i;
46 char *data = NULL;
47 const char title[] = "# Configuration\n\n";
48
49 if (!(data = dyn_strcat(NULL, &length, V(header)))) goto fail;
50 if (!(data = dyn_strcat(data, &length, V(title)))) goto fail;
51
52 for (i = 0; i < LENGTH(fields); i++) {
53 char buf[2048];
54 int len = 0;
55 char *info = fields[i].restart ? "(Restart required)" : "";
56 switch (fields[i].type) {
57 case VALUE_INT:
58 len = snprintf(V(buf), "=>%d %s = %d %s\n", i,
59 fields[i].name, *(int*)fields[i].ptr,
60 info);
61 break;
62 case VALUE_STRING:
63 len = snprintf(V(buf), "=>%d %s = %s %s\n", i,
64 fields[i].name, (char*)fields[i].ptr,
65 info);
66 break;
67 }
68 if (!len) continue;
69 if (!(data = dyn_strcat(data, &length, buf, len))) goto fail;
70 }
71
72 *out = data;
73 *length_out = length;
74 return 0;
75 fail:
76 free(data);
77 return ERROR_MEMORY_FAILURE;
78 }
79