Sanitized public release v1.0.3

Source-Tag: v1.0.3
Manifest-SHA256: b7b09bf48f9e092ed8ad82f99c0319d6c3837d0a1549bd0cc4a374276c0f3896
This commit is contained in:
NIA Sanitized Release Publisher
2026-07-20 22:35:36 +00:00
commit 7141326ea0
41 changed files with 6397 additions and 0 deletions
@@ -0,0 +1,327 @@
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <weechat/weechat-plugin.h>
WEECHAT_PLUGIN_NAME("neodrop_manager")
WEECHAT_PLUGIN_DESCRIPTION("NeoDrop manager control buffer")
WEECHAT_PLUGIN_AUTHOR("{{PRODUCT_NAME}}")
WEECHAT_PLUGIN_VERSION("1.1")
WEECHAT_PLUGIN_LICENSE("GPL3")
#define CONTROL_SOCKET "{{MANAGER_CONTROL_SOCKET_PATH}}"
#define SEND_LIMIT 8192U
#define RECEIVE_LIMIT 16384U
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
struct t_weechat_plugin *weechat_plugin;
static struct t_gui_buffer *manager_buffer;
static struct t_hook *manager_fd_hook;
static int manager_fd = -1;
static char receive_buffer[RECEIVE_LIMIT];
static size_t receive_length;
static void print_error(const char *message)
{
if (manager_buffer != NULL)
weechat_printf(manager_buffer, "%s%s", weechat_color("lightred"), message);
}
static void disconnect_manager(int announce)
{
int was_connected = manager_fd >= 0;
if (manager_fd_hook != NULL) {
weechat_unhook(manager_fd_hook);
manager_fd_hook = NULL;
}
if (manager_fd >= 0)
close(manager_fd);
manager_fd = -1;
receive_length = 0;
if (announce && was_connected)
print_error("NeoDrop manager disconnected; reconnecting in the background.");
}
static void print_protocol_line(const char *line, size_t length)
{
const char *payload;
const char *color = NULL;
size_t payload_length;
size_t index;
char output[RECEIVE_LIMIT];
if (manager_buffer == NULL)
return;
if (length > 0 && line[length - 1] == '\r')
length--;
if (length >= 5 && memcmp(line, "LINE\t", 5) == 0) {
payload = line + 5;
payload_length = length - 5;
} else if (length >= 6 && memcmp(line, "ERROR\t", 6) == 0) {
payload = line + 6;
payload_length = length - 6;
color = "lightred";
} else {
print_error("NeoDrop manager sent an invalid response.");
return;
}
for (index = 0; index < payload_length; index++) {
unsigned char byte = (unsigned char)payload[index];
output[index] = (byte < 0x20U || byte == 0x7fU) ? ' ' : (char)byte;
}
output[payload_length] = '\0';
if (color != NULL)
weechat_printf(manager_buffer, "%s%s", weechat_color(color), output);
else
weechat_printf(manager_buffer, "%s", output);
}
static int manager_read_cb(const void *pointer, void *data, int fd)
{
ssize_t count;
size_t consumed = 0;
char *newline;
(void)pointer;
(void)data;
(void)fd;
if (receive_length >= RECEIVE_LIMIT - 1U) {
print_error("NeoDrop manager response exceeded the line limit.");
disconnect_manager(0);
return WEECHAT_RC_OK;
}
count = recv(manager_fd, receive_buffer + receive_length,
RECEIVE_LIMIT - receive_length - 1U, 0);
if (count < 0 && errno == EINTR)
return WEECHAT_RC_OK;
if (count <= 0) {
disconnect_manager(1);
return WEECHAT_RC_OK;
}
receive_length += (size_t)count;
while (consumed < receive_length) {
size_t available = receive_length - consumed;
newline = memchr(receive_buffer + consumed, '\n', available);
if (newline == NULL)
break;
print_protocol_line(receive_buffer + consumed,
(size_t)(newline - (receive_buffer + consumed)));
consumed = (size_t)(newline - receive_buffer) + 1U;
}
if (consumed > 0) {
receive_length -= consumed;
memmove(receive_buffer, receive_buffer + consumed, receive_length);
}
if (receive_length >= RECEIVE_LIMIT - 1U) {
print_error("NeoDrop manager response exceeded the line limit.");
disconnect_manager(0);
}
return WEECHAT_RC_OK;
}
static int connect_manager(void)
{
struct sockaddr_un address;
int fd;
if (manager_fd >= 0)
return 1;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return 0;
#ifdef SO_NOSIGPIPE
{
int enabled = 1;
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &enabled, sizeof(enabled)) != 0) {
close(fd);
return 0;
}
}
#endif
memset(&address, 0, sizeof(address));
address.sun_family = AF_UNIX;
memcpy(address.sun_path, CONTROL_SOCKET, sizeof(CONTROL_SOCKET));
if (connect(fd, (struct sockaddr *)&address, sizeof(address)) != 0) {
close(fd);
return 0;
}
manager_fd = fd;
manager_fd_hook = weechat_hook_fd(manager_fd, 1, 0, 0,
&manager_read_cb, NULL, NULL);
if (manager_fd_hook == NULL) {
disconnect_manager(0);
return 0;
}
return 1;
}
static void send_command(const char *command)
{
static const char prefix[] = "COMMAND\t";
char message[SEND_LIMIT];
size_t command_length;
size_t message_length;
size_t sent = 0;
if (command == NULL || command[0] == '\0')
return;
command_length = strlen(command);
if (command_length > SEND_LIMIT - sizeof("COMMAND\t\n")) {
print_error("NeoDrop manager command exceeded the line limit.");
return;
}
if (strpbrk(command, "\t\r\n") != NULL) {
print_error("NeoDrop manager commands cannot contain tabs or newlines.");
return;
}
if (!connect_manager()) {
print_error("Unable to connect to the NeoDrop manager.");
return;
}
memcpy(message, prefix, sizeof(prefix) - 1U);
memcpy(message + sizeof(prefix) - 1U, command, command_length);
message_length = sizeof(prefix) - 1U + command_length;
message[message_length++] = '\n';
while (sent < message_length) {
ssize_t count = send(manager_fd, message + sent, message_length - sent,
MSG_NOSIGNAL);
if (count < 0 && errno == EINTR)
continue;
if (count <= 0) {
disconnect_manager(1);
return;
}
sent += (size_t)count;
}
}
static int reconnect_cb(const void *pointer, void *data, int remaining_calls)
{
(void)pointer;
(void)data;
(void)remaining_calls;
(void)connect_manager();
return WEECHAT_RC_OK;
}
static int input_cb(const void *pointer, void *data, struct t_gui_buffer *buffer,
const char *input)
{
(void)pointer;
(void)data;
(void)buffer;
send_command(input);
return WEECHAT_RC_OK;
}
static int close_cb(const void *pointer, void *data, struct t_gui_buffer *buffer)
{
(void)pointer;
(void)data;
(void)buffer;
manager_buffer = NULL;
return WEECHAT_RC_OK;
}
static int ensure_buffer(void)
{
if (manager_buffer == NULL)
manager_buffer = weechat_buffer_search("neodrop_manager", "control");
if (manager_buffer == NULL) {
manager_buffer = weechat_buffer_new("control", &input_cb, NULL, NULL,
&close_cb, NULL, NULL);
if (manager_buffer == NULL)
return 0;
}
weechat_buffer_set_pointer(manager_buffer, "input_callback", &input_cb);
weechat_buffer_set_pointer(manager_buffer, "close_callback", &close_cb);
weechat_buffer_set(manager_buffer, "short_name", "NeoDrop");
weechat_buffer_set(manager_buffer, "title",
"NeoDrop | list | put-text NAME TEXT | show/read/download/delete ID | edit ID | help");
weechat_buffer_set(manager_buffer, "hidden", "0");
weechat_buffer_set(manager_buffer, "notify", "3");
weechat_buffer_set(manager_buffer, "localvar_set_no_log", "1");
weechat_buffer_set(manager_buffer, "localvar_set_pinned", "true");
weechat_buffer_set(manager_buffer, "localvar_set_type", "other");
return 1;
}
static int command_cb(const void *pointer, void *data, struct t_gui_buffer *buffer,
int argc, char **argv, char **argv_eol)
{
const char *command = NULL;
int background_registration;
(void)pointer;
(void)data;
(void)buffer;
(void)argv;
if (argc > 1 && argv_eol != NULL && argv_eol[1] != NULL && argv_eol[1][0] != '\0')
command = argv_eol[1];
background_registration = command != NULL && strncmp(command, "register ", 9) == 0;
if (!ensure_buffer())
return WEECHAT_RC_ERROR;
if (!background_registration)
weechat_buffer_set(manager_buffer, "display", "1");
if (command != NULL)
send_command(command);
else
send_command("list");
return WEECHAT_RC_OK;
}
int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
{
(void)argc;
(void)argv;
weechat_plugin = plugin;
if (!ensure_buffer())
return WEECHAT_RC_ERROR;
if (weechat_hook_command("drops", "open/control NeoDrop manager",
"list || status || help || put-text <name> <text> || show <selector> || read <selector> || download <selector> || delete <selector> || edit <selector> || line <number> <text> || insert <number> <text> || delete-line <number> || save || cancel",
"Manage encrypted NeoDrop files and text revisions",
"list|status|help|put-text|show|read|download|delete|edit|line|insert|delete-line|save|cancel",
&command_cb, NULL, NULL) == NULL)
return WEECHAT_RC_ERROR;
if (weechat_hook_timer(5000, 0, 0, &reconnect_cb, NULL, NULL) == NULL)
return WEECHAT_RC_ERROR;
return WEECHAT_RC_OK;
}
int weechat_plugin_end(struct t_weechat_plugin *plugin)
{
(void)plugin;
disconnect_manager(0);
return WEECHAT_RC_OK;
}