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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
#ifndef HYBBX_SESSION_H
#define HYBBX_SESSION_H
#include "hybbx/plugin.h"
#include "hybbx/storage.h"
#include "hybbx/mail.h"
#include "hybbx/proxymail.h"
#ifdef __cplusplus
extern "C" {
#endif
struct hybbx_service;
typedef enum hybbx_session_area {
HYBBX_AREA_MAIN = 1,
HYBBX_AREA_MAIL = 2,
HYBBX_AREA_CHAT = 3,
HYBBX_AREA_CONFERENCE = 4,
/** Inter-Main mail sub-area under mail (`/proxymail`, `/mail proxymail`). */
HYBBX_AREA_PROXYMAIL = 5,
/** Inter-Main chat sub-area under chat (`/proxychat`, `/chat proxychat`). */
HYBBX_AREA_PROXYCHAT = 6
} hybbx_session_area_t;
/** Maximum nested area depth (main + sub-areas). */
#define HYBBX_AREA_STACK_MAX 8u
/**
* Open a new connection session.
* When auto-login is enabled (default), assigns the next free Guest1 … Guest25
* slot in memory (not written to user files).
* When auto-login is disabled, the session stays at a login prompt for
* registered `/login` and `/register` only (no guest slots).
*/
hybbx_result_t hybbx_session_open(struct hybbx_service *service,
const hybbx_transport_plugin_t *transport,
void *transport_data,
hybbx_session_t **out);
void hybbx_session_close(hybbx_session_t *session);
hybbx_result_t hybbx_session_handle_input(hybbx_session_t *session,
const uint8_t *data, size_t len);
const char *hybbx_session_username(const hybbx_session_t *session);
/** User-facing name (nickname) for the logged-in account. */
const char *hybbx_session_display_name(const hybbx_session_t *session);
/**
* Format `username@plugin` (transport name) into @p out.
* Uses display name and session transport / record.
*/
hybbx_result_t hybbx_session_format_user_at_plugin(const hybbx_session_t *session,
char *out, size_t out_len);
uint64_t hybbx_session_id(const hybbx_session_t *session);
const hybbx_session_record_t *hybbx_session_record(const hybbx_session_t *session);
/** Store the client peer address on the session record (for security.log). */
hybbx_result_t hybbx_session_set_remote(hybbx_session_t *session,
const char *remote);
hybbx_user_level_t hybbx_session_user_level(const hybbx_session_t *session);
int hybbx_session_is_guest(const hybbx_session_t *session);
/** Non-zero for telnet, SSH, or WebSocket — not plugin/link transports. */
int hybbx_session_is_interactive_user(const hybbx_session_t *session);
/**
* Non-zero when this Sysop is hidden from /who and /online:
* [monitor] invisible-sysop=yes, or /monitor on.
* Non-Sysop grant users are never hidden.
*/
int hybbx_session_hidden_from_who(const hybbx_session_t *session);
int hybbx_session_monitor_active(const hybbx_session_t *session);
void hybbx_session_set_monitor_active(hybbx_session_t *session, int on);
/** Non-zero when the session has completed login (guest or registered). */
int hybbx_session_logged_in(const hybbx_session_t *session);
/** Non-zero when auto_login is off: banner + prompt, registered login only. */
int hybbx_session_login_prompt(const hybbx_session_t *session);
/** Write raw text to the connected client (no line ending, no prompt). */
hybbx_result_t hybbx_session_write(hybbx_session_t *session, const char *text);
/** Write a line and append CRLF. */
hybbx_result_t hybbx_session_write_line(hybbx_session_t *session,
const char *text);
/** One blank line before `/command` output (not chat/mail compose). */
hybbx_result_t hybbx_session_command_gap(hybbx_session_t *session);
/**
* Show the global input prompt when configured.
* Default (empty prompt): no output — users type on a blank line.
*/
hybbx_result_t hybbx_session_show_prompt(hybbx_session_t *session);
/** Clear screen and discard the current input line; show prompt when set. */
hybbx_result_t hybbx_session_clear_terminal(hybbx_session_t *session);
/** Non-zero when typed characters are echoed back to the client. */
int hybbx_session_input_echo(const hybbx_session_t *session);
/** Enable or disable per-session input echo. */
hybbx_result_t hybbx_session_set_input_echo(hybbx_session_t *session, int enabled);
/** Current session area (main, mail, chat, …). */
hybbx_session_area_t hybbx_session_area(const hybbx_session_t *session);
/** Area name: main, mail, chat. */
const char *hybbx_session_area_name(hybbx_session_area_t area);
/** Parse area name (main, mail, chat). */
hybbx_session_area_t hybbx_session_area_parse(const char *name);
/** Go up one area level (alias: /back). Clears state for the area being left. */
hybbx_result_t hybbx_session_leave_area(hybbx_session_t *session);
/** Return to main from any depth (alias: /menu). Clears all sub-area state. */
hybbx_result_t hybbx_session_go_main(hybbx_session_t *session);
/** Enter an area (pushes onto the area stack). */
hybbx_result_t hybbx_session_enter_area(hybbx_session_t *session,
hybbx_session_area_t area);
/** Switch the session to a registered (non-guest) account after login. */
hybbx_result_t hybbx_session_switch_user(hybbx_session_t *session,
const hybbx_user_record_t *user);
/**
* Periodic session maintenance (guest time limit, etc.).
* @return HYBBX_SESSION_END when the session should be closed.
*/
hybbx_result_t hybbx_session_tick(hybbx_session_t *session);
/** Join a chat channel (enters chat area). @p channel_index is 1-based. */
hybbx_result_t hybbx_session_join_chat_channel(hybbx_session_t *session,
unsigned channel_index);
/** Current chat channel (1-based), or 0 when not in chat. */
unsigned hybbx_session_chat_channel(const hybbx_session_t *session);
struct hybbx_service *hybbx_session_service(hybbx_session_t *session);
/** Join a private conference (conference area). Internal — use hybbx_conference_start. */
hybbx_result_t hybbx_session_join_conference(hybbx_session_t *session,
const char *topic,
const char *partner_username);
void hybbx_session_clear_conference(hybbx_session_t *session);
int hybbx_session_conference_may_invite(hybbx_session_t *session,
const char *target);
void hybbx_session_conference_invite_sent(hybbx_session_t *session,
const char *target);
void hybbx_session_set_conference_invite(hybbx_session_t *session,
const char *from_username,
const char *topic);
/** Optional deadline (0 = none). Used by monitor-initiated invites. */
void hybbx_session_set_conference_invite_deadline(hybbx_session_t *session,
time_t deadline);
time_t hybbx_session_conference_invite_deadline(const hybbx_session_t *session);
void hybbx_session_clear_conference_invite(hybbx_session_t *session);
const char *hybbx_session_conference_invite_from(const hybbx_session_t *session);
const char *hybbx_session_conference_invite_topic(const hybbx_session_t *session);
const char *hybbx_session_conference_partner(const hybbx_session_t *session);
/** Enter local mail area (does not enter proxymail). */
hybbx_result_t hybbx_session_enter_mail(hybbx_session_t *session);
/** Enter proxymail sub-area (pushes mail when needed). */
hybbx_result_t hybbx_session_enter_proxymail(hybbx_session_t *session);
/** Enter local chat area without joining a channel. */
hybbx_result_t hybbx_session_enter_chat(hybbx_session_t *session);
/** Enter proxychat sub-area (pushes chat when needed). */
hybbx_result_t hybbx_session_enter_proxychat(hybbx_session_t *session);
/** Non-zero when composing an outbound mail message. */
int hybbx_session_mail_composing(const hybbx_session_t *session);
/** Start mail compose to @p to_user with @p subject; enters mail area. */
hybbx_result_t hybbx_session_mail_compose_start(hybbx_session_t *session,
const char *to_user,
const char *subject);
/** Cancel an in-progress mail compose. */
void hybbx_session_mail_compose_cancel(hybbx_session_t *session);
/** Body accumulated so far during compose (NUL-terminated). */
const char *hybbx_session_mail_compose_body(const hybbx_session_t *session);
const char *hybbx_session_mail_compose_to(const hybbx_session_t *session);
const char *hybbx_session_mail_compose_subject(const hybbx_session_t *session);
/** Non-zero when composing proxymail (`user@remote-main` recipient). */
int hybbx_session_proxymail_composing(const hybbx_session_t *session);
hybbx_result_t hybbx_session_proxymail_compose_start(hybbx_session_t *session,
const char *to_address,
const char *subject);
void hybbx_session_proxymail_compose_cancel(hybbx_session_t *session);
const char *hybbx_session_proxymail_compose_body(const hybbx_session_t *session);
const char *hybbx_session_proxymail_compose_to(const hybbx_session_t *session);
const char *hybbx_session_proxymail_compose_subject(
const hybbx_session_t *session);
/** Wall-clock time when this session connected (for bandwidth policy ordering). */
time_t hybbx_session_connected_at(const hybbx_session_t *session);
/** Non-zero when the session is frozen by circuit bandwidth limits. */
int hybbx_session_bandwidth_paused(const hybbx_session_t *session);
void hybbx_session_set_bandwidth_paused(hybbx_session_t *session, int paused);
/**
* End the session after sending @ref HYBBX_BANDWIDTH_DISCONNECT_MSG.
* Newest-first under low-bandwidth link pressure.
*/
void hybbx_session_disconnect_bandwidth(hybbx_session_t *session);
#ifdef __cplusplus
}
#endif
#endif /* HYBBX_SESSION_H */
|