1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#ifndef UMBRELLA_H
#define UMBRELLA_H
#include <stdint.h>
#include <sys/types.h>
/* ── Version ─────────────────────────────────────────────────────────────── */
#define UMBRELLA_VERSION "0.1.0"
/* ── Paths ───────────────────────────────────────────────────────────────── */
#define UMBRELLA_CONF_DIR "/etc/umbrella"
#define UMBRELLA_UNITS_DIR "/etc/umbrella/units"
#define UMBRELLA_CONF_FILE "/etc/umbrella/umbrella.conf"
#define UMBRELLA_SOCK_PATH "/run/umbrella/umbrella.sock"
#define UMBRELLA_PID_FILE "/run/umbrella/umbrella.pid"
#define UMBRELLA_LOG_FILE "/var/log/umbrella/umbrella.log"
/* ── Limits ──────────────────────────────────────────────────────────────── */
#define MAX_UNITS 64
#define MAX_CLIENTS 32
#define MAX_NAME 64
#define MAX_PATH 256
#define MAX_DISPLAY 128
#define MAX_ACTIONS 16
#define RING_BUF_LINES 500 /* output lines buffered per unit */
#define RING_BUF_LINE_MAX 1024 /* max bytes per buffered line */
#define PROTO_MAX_MSG 65536 /* max wire message size */
/* ── Console types ───────────────────────────────────────────────────────── */
typedef enum {
CONSOLE_RCON = 0,
CONSOLE_STDIN = 1,
} ConsoleType;
/* ── Health check types ──────────────────────────────────────────────────── */
typedef enum {
HEALTH_A2S = 0,
HEALTH_TCP = 1,
HEALTH_NONE = 2,
} HealthType;
/* ── Process state ───────────────────────────────────────────────────────── */
typedef enum {
STATE_STOPPED = 0,
STATE_STARTING = 1,
STATE_RUNNING = 2,
STATE_CRASHED = 3,
STATE_STOPPING = 4,
} ProcessState;
/* ── Action: a named script ──────────────────────────────────────────────── */
typedef struct {
char name[MAX_NAME];
char script[MAX_PATH];
} Action;
/* ── Console config ──────────────────────────────────────────────────────── */
typedef struct {
ConsoleType type;
char host[64];
uint16_t port;
char password[128]; /* RCON password; empty for stdin */
char password_env[64]; /* env var name to read password from */
} ConsoleConfig;
/* ── Health config ───────────────────────────────────────────────────────── */
typedef struct {
HealthType type;
char host[64];
uint16_t port;
int timeout_ms;
} HealthConfig;
/* ── Ring buffer: circular store of recent output lines ──────────────────── */
typedef struct {
char lines[RING_BUF_LINES][RING_BUF_LINE_MAX];
int head; /* next write position */
int count; /* how many lines are valid */
} RingBuffer;
/* ── Unit: a loaded descriptor ───────────────────────────────────────────── */
typedef struct {
char name[MAX_NAME];
char display[MAX_DISPLAY];
char service[MAX_NAME]; /* systemd unit name, informational */
char broadcast_cmd[128]; /* command template for !broadcast, e.g. "say {msg}" */
ConsoleConfig console;
HealthConfig health;
char log_paths[4][MAX_PATH];
int log_count;
Action actions[MAX_ACTIONS];
int action_count;
char log_filter[MAX_PATH]; /* path to filter executable, or empty */
char log_dir[MAX_PATH]; /* directory to watch, or "" if not used */
char log_dir_pattern[MAX_PATH]; /* fnmatch pattern for log files; default "*" */
/* Runtime state (populated by process/rcon layer, not yaml) */
ProcessState state;
pid_t pid; /* only for CONSOLE_STDIN */
int stdin_fd; /* only for CONSOLE_STDIN */
int stdout_fd; /* only for CONSOLE_STDIN */
RingBuffer *output;
/* Log filter subprocess (populated at runtime if log_filter is set) */
pid_t filter_pid;
int filter_in_fd; /* write end: daemon → filter stdin */
int filter_out_fd; /* read end: filter stdout → daemon */
} Unit;
/* ── Client: a connected socket client ───────────────────────────────────── */
typedef struct {
int fd;
char attached[MAX_NAME]; /* unit name, or empty if not attached */
int uid; /* peer uid from SO_PEERCRED */
} Client;
/* ── Global daemon state ─────────────────────────────────────────────────── */
typedef struct {
Unit units[MAX_UNITS];
int unit_count;
Client clients[MAX_CLIENTS];
int client_count;
int epoll_fd;
int listen_fd;
int signal_fd;
int running;
} Daemon;
extern Daemon g;
#endif /* UMBRELLA_H */
|