summaryrefslogtreecommitdiff
path: root/src/umbrella.h
blob: ff1873f27dae910acab82c1e57356fc2a518af9a (plain)
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
#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 */

    /* 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 */