blob: b25fa2468bdff7c39989ac7385fb0ec931d7ebd9 [file] [log] [blame]
Harald Welte81e20232018-06-04 21:25:56 +02001/* Simple Osmocom System Monitor (osysmon): Support for monitoring files */
2
3/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved.
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Harald Welte81e20232018-06-04 21:25:56 +020017 */
18
19#include <string.h>
20#include <sys/sysinfo.h>
21
22#include <osmocom/vty/vty.h>
23#include <osmocom/vty/command.h>
24
25#include "osysmon.h"
26#include "value_node.h"
27
28/***********************************************************************
29 * Data model
30 ***********************************************************************/
31
32struct osysmon_file {
33 struct llist_head list;
34 struct {
35 const char *name;
36 const char *path;
37 } cfg;
38};
39
40static struct osysmon_file *osysmon_file_find(const char *name)
41{
42 struct osysmon_file *of;
43
44 llist_for_each_entry(of, &g_oss->files, list) {
45 if (!strcmp(of->cfg.name, name))
46 return of;
47 }
48 return NULL;
49}
50
51static struct osysmon_file *osysmon_file_add(const char *name, const char *path)
52{
53 struct osysmon_file *of;
54
55 if (osysmon_file_find(name))
56 return NULL;
57
58 of = talloc_zero(g_oss, struct osysmon_file);
59 OSMO_ASSERT(of);
60 of->cfg.name = talloc_strdup(of, name);
61 of->cfg.path = talloc_strdup(of, path);
62 llist_add_tail(&of->list, &g_oss->files);
63 return of;
64}
65
66static void osysmon_file_destroy(struct osysmon_file *of)
67{
68 llist_del(&of->list);
69 talloc_free(of);
70}
71
72static void osysmon_file_read(struct osysmon_file *of, struct value_node *parent)
73{
74 char buf[512];
Stefan Sperling908d3cc2018-11-27 11:47:41 +010075 char *s, *nl;
Harald Welte81e20232018-06-04 21:25:56 +020076 FILE *f;
77
78 f = fopen(of->cfg.path, "r");
79 if (!f) {
Maxf41973e2019-01-25 18:40:11 +010080 value_node_add(parent, of->cfg.name, "<NOTFOUND>");
Harald Welte81e20232018-06-04 21:25:56 +020081 return;
82 }
Stefan Sperling908d3cc2018-11-27 11:47:41 +010083 s = fgets(buf, sizeof(buf), f);
84 fclose(f);
85 if (s == NULL) {
Maxf41973e2019-01-25 18:40:11 +010086 value_node_add(parent, of->cfg.name, "<EMPTY>");
Harald Welte81e20232018-06-04 21:25:56 +020087 return;
88 }
89 buf[sizeof(buf)-1] = '\0';
90 while ((nl = strrchr(buf, '\n')))
91 *nl = '\0';
Maxf41973e2019-01-25 18:40:11 +010092 value_node_add(parent, of->cfg.name, buf);
Harald Welte81e20232018-06-04 21:25:56 +020093}
94
95/***********************************************************************
96 * VTY
97 ***********************************************************************/
98
99#define FILE_STR "Configure a file to be monitored/watched\n"
100DEFUN(cfg_file, cfg_file_cmd,
101 "file NAME PATH",
102 FILE_STR "Name of this file-watcher\n" "Path of file in filesystem\n")
103{
104 struct osysmon_file *of;
105 of = osysmon_file_add(argv[0], argv[1]);
106 if (!of) {
107 vty_out(vty, "Couldn't add file-watcher, maybe it exists?%s", VTY_NEWLINE);
108 return CMD_WARNING;
109 }
110 return CMD_SUCCESS;
111}
112
113DEFUN(cfg_no_file, cfg_no_file_cmd,
114 "no file NAME",
115 NO_STR FILE_STR "Name of this file-watcher\n")
116{
117 struct osysmon_file *of;
118 of = osysmon_file_find(argv[0]);
119 if (!of) {
120 vty_out(vty, "Cannot find file-watcher for '%s'%s", argv[0], VTY_NEWLINE);
121 return CMD_WARNING;
122 }
123 osysmon_file_destroy(of);
124 return CMD_SUCCESS;
125}
126
127
128static void osysmon_file_vty_init(void)
129{
130 install_element(CONFIG_NODE, &cfg_file_cmd);
131 install_element(CONFIG_NODE, &cfg_no_file_cmd);
132}
133
134/***********************************************************************
135 * Runtime Code
136 ***********************************************************************/
137
138/* called once on startup before config file parsing */
139int osysmon_file_init()
140{
141 osysmon_file_vty_init();
142 return 0;
143}
144
145/* called periodically */
146int osysmon_file_poll(struct value_node *parent)
147{
148 struct value_node *vn_file;
149 struct osysmon_file *of;
150
Daniel Willmann85d0fb22019-11-07 16:59:15 +0100151 if (llist_empty(&g_oss->files))
152 return 0;
153
Maxf41973e2019-01-25 18:40:11 +0100154 vn_file = value_node_add(parent, "file", NULL);
Harald Welte81e20232018-06-04 21:25:56 +0200155
156 llist_for_each_entry(of, &g_oss->files, list)
157 osysmon_file_read(of, vn_file);
158
159 return 0;
160}