refactor
This commit is contained in:
parent
5ed254e0b5
commit
c9815c36f0
@ -1,6 +1,6 @@
|
||||
# Over engineered custom network protocol experiment
|
||||
|
||||
ABANDONED! Because I hated how complicated the protocol was, and just had no more motivation to continue.
|
||||
This was created based of the youtube, but was heavily modified. Didn't like it.
|
||||
|
||||
Youtube tutorial: https://www.youtube.com/watch?v=AS_nxNS6YKY
|
||||
|
||||
|
21
build.zig
21
build.zig
@ -1,11 +1,12 @@
|
||||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
|
||||
fn linkPkgConfigOutput(b: *std.build.Builder, obj: *std.build.LibExeObjStep, pkg_config_args: []const []const u8) !void {
|
||||
fn linkPkgConfigOutput(b: *Build, obj: *Build.Step.Compile, pkg_config_args: []const []const u8) !void {
|
||||
var argv = std.ArrayList([]const u8).init(b.allocator);
|
||||
try argv.append("pkg-config");
|
||||
try argv.appendSlice(pkg_config_args);
|
||||
|
||||
const result = try std.ChildProcess.exec(.{
|
||||
const result = try std.ChildProcess.run(.{
|
||||
.allocator = b.allocator,
|
||||
.argv = argv.items
|
||||
});
|
||||
@ -21,7 +22,7 @@ fn linkPkgConfigOutput(b: *std.build.Builder, obj: *std.build.LibExeObjStep, pkg
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(b: *std.build.Builder) !void {
|
||||
pub fn build(b: *Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
@ -31,22 +32,21 @@ pub fn build(b: *std.build.Builder) !void {
|
||||
.optimize = optimize,
|
||||
});
|
||||
libflex.addCSourceFile(.{
|
||||
.file = .{ .path = "libflex/libflex.c" },
|
||||
.file = b.path("libflex/libflex.c"),
|
||||
.flags = &.{}
|
||||
});
|
||||
libflex.linkLibC();
|
||||
libflex.installHeader("libflex/libflex.h", "libflex.h");
|
||||
libflex.installHeader(b.path("libflex/libflex.h"), "libflex.h");
|
||||
|
||||
{
|
||||
const rolexhound = b.addExecutable(.{
|
||||
.name = "rolexhound",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = .{ .path = "rolexhound/main.c" }
|
||||
.optimize = optimize
|
||||
});
|
||||
rolexhound.addCSourceFile(.{ .file = b.path("rolexhound/main.c") });
|
||||
rolexhound.linkLibrary(libflex);
|
||||
rolexhound.linkLibC();
|
||||
try linkPkgConfigOutput(b, rolexhound, &.{ "--cflags", "--libs", "libnotify" });
|
||||
|
||||
b.installArtifact(rolexhound);
|
||||
|
||||
@ -63,11 +63,12 @@ pub fn build(b: *std.build.Builder) !void {
|
||||
const smartwatch = b.addExecutable(.{
|
||||
.name = "smartwatch",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = .{ .path = "smartwatch/main.c" }
|
||||
.optimize = optimize
|
||||
});
|
||||
smartwatch.addCSourceFile(.{ .file = b.path("smartwatch/main.c") });
|
||||
smartwatch.linkLibrary(libflex);
|
||||
smartwatch.linkLibC();
|
||||
try linkPkgConfigOutput(b, smartwatch, &.{ "--cflags", "--libs", "libnotify" });
|
||||
|
||||
b.installArtifact(smartwatch);
|
||||
|
||||
|
@ -1,206 +1,212 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libflex.h"
|
||||
|
||||
#define ARRAY_LEN(arr) sizeof(arr) / sizeof(arr[0])
|
||||
|
||||
const flx_opt OPTION_RANGES[5] = {
|
||||
FLX_WATCH_REM,
|
||||
FLX_QUIT_ERROR,
|
||||
FLX_NOTIFY_MOVE,
|
||||
FLX_REPLY_INVALID_DATA,
|
||||
FLX_STATUS_ERR_READ_INOTIFY,
|
||||
};
|
||||
|
||||
const flx_opt ACTION_SIZES[5] = {
|
||||
FLX_DLEN_WATCH,
|
||||
FLX_DLEN_QUIT,
|
||||
FLX_DLEN_NOTIFY,
|
||||
FLX_DLEN_REPLY,
|
||||
FLX_DLEN_STATUS,
|
||||
};
|
||||
|
||||
const flx_opt LAST_ACTION_INDEX = ARRAY_LEN(OPTION_RANGES) - 1;
|
||||
|
||||
void flx_serialize_result_init(struct flx_serialize_result *result) {
|
||||
result->size = -1;
|
||||
result->reply = FLX_REPLY_UNSET;
|
||||
void flx_msg_init_quit(struct flx_msg *msg, enum flx_opt_quit opt) {
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->action = FLX_ACT_QUIT;
|
||||
msg->option = opt;
|
||||
}
|
||||
|
||||
void flx_msg_init(struct flx_msg *msg) {
|
||||
msg->action = FLX_ACT_UNSET;
|
||||
msg->option = FLX_UNSET_UNSET;
|
||||
msg->size = 0;
|
||||
|
||||
msg->data = NULL;
|
||||
msg->data_len = 0;
|
||||
void flx_msg_init_add_watch(struct flx_msg *msg, const char *filename) {
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->action = FLX_ACT_WATCH;
|
||||
msg->option = FLX_WATCH_ADD;
|
||||
msg->data_len = 1;
|
||||
msg->data[0].ptr = filename;
|
||||
msg->data[0].len = strlen(filename);
|
||||
}
|
||||
|
||||
void flx_msg_free(struct flx_msg *msg) {
|
||||
if (msg->data == NULL) return;
|
||||
|
||||
for (int i = 0; i < msg->data_len; i++) {
|
||||
if (msg->data[i] == NULL) continue;
|
||||
free(msg->data[i]);
|
||||
}
|
||||
free(msg->data);
|
||||
|
||||
msg->data = NULL;
|
||||
void flx_msg_init_notify(struct flx_msg *msg, enum flx_opt_notify opt, const char *base_path, const char *path) {
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->action = FLX_ACT_NOTIFY;
|
||||
msg->option = opt;
|
||||
msg->data_len = 2;
|
||||
msg->data[0].ptr = base_path;
|
||||
msg->data[0].len = strlen(base_path);
|
||||
msg->data[1].ptr = path;
|
||||
msg->data[1].len = strlen(path);
|
||||
}
|
||||
|
||||
void flx_msg_reset(struct flx_msg *msg) {
|
||||
flx_msg_free(msg);
|
||||
flx_msg_init(msg);
|
||||
void flx_msg_init_remove_watch(struct flx_msg *msg, const char *filename) {
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->action = FLX_ACT_WATCH;
|
||||
msg->option = FLX_WATCH_REM;
|
||||
msg->data_len = 1;
|
||||
msg->data[0].ptr = filename;
|
||||
msg->data[0].len = strlen(filename);
|
||||
}
|
||||
|
||||
void flx_serialize(
|
||||
uint8_t out_buffer[FLX_PKT_MAXIMUM_SIZE],
|
||||
struct flx_msg *msg,
|
||||
struct flx_serialize_result *result
|
||||
) {
|
||||
int valid_data_length = -1;
|
||||
uint8_t data_size = 0;
|
||||
flx_serialize_result_init(result);
|
||||
|
||||
if (msg->action <= LAST_ACTION_INDEX) {
|
||||
out_buffer[0] = msg->action;
|
||||
valid_data_length = ACTION_SIZES[msg->action];
|
||||
} else {
|
||||
result->reply = FLX_REPLY_BAD_ACTION;
|
||||
return;
|
||||
static bool write_uint8(uint8_t *buffer, size_t capacity, size_t *cursor, uint8_t value) {
|
||||
if ((*cursor) + 1 < capacity) {
|
||||
buffer[*cursor] = value;
|
||||
(*cursor)++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (valid_data_length != msg->data_len) {
|
||||
result->reply = FLX_REPLY_BAD_SIZE;
|
||||
return;
|
||||
static uint8_t *read_uint8_array(uint8_t *buffer, size_t capacity, size_t *cursor, uint8_t byte_count) {
|
||||
if ((*cursor) + byte_count > capacity) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->option > OPTION_RANGES[msg->option]) {
|
||||
result->reply = FLX_REPLY_BAD_OPTION;
|
||||
return;
|
||||
uint8_t *array = &buffer[*cursor];
|
||||
(*cursor) += byte_count;
|
||||
return array;
|
||||
}
|
||||
|
||||
out_buffer[1] = msg->option;
|
||||
static bool read_uint8(uint8_t *buffer, size_t capacity, size_t *cursor, uint8_t *value) {
|
||||
uint8_t *array = read_uint8_array(buffer, capacity, cursor, 1);
|
||||
if (array) {
|
||||
*value = array[0];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (valid_data_length != 0 && msg->data == NULL) {
|
||||
result->reply = FLX_REPLY_INVALID_DATA;
|
||||
return;
|
||||
int flx_serialize(uint8_t *out_buffer, size_t capacity, struct flx_msg *msg) {
|
||||
size_t cursor = 0;
|
||||
|
||||
if (!write_uint8(out_buffer, capacity, &cursor, msg->action)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t expected_data_len = 0;
|
||||
if (msg->action == FLX_ACT_WATCH) {
|
||||
expected_data_len = 1;
|
||||
} else if (msg->action == FLX_ACT_NOTIFY) {
|
||||
expected_data_len = 2;
|
||||
}
|
||||
|
||||
if (expected_data_len != msg->data_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!write_uint8(out_buffer, capacity, &cursor, msg->option)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!write_uint8(out_buffer, capacity, &cursor, msg->data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->data_len > FLX_DATA_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < msg->data_len; i++) {
|
||||
if (msg->data[i] == NULL) {
|
||||
result->reply = FLX_REPLY_INVALID_DATA;
|
||||
return;
|
||||
struct char_slice *data_i = &msg->data[i];
|
||||
|
||||
if (!write_uint8(out_buffer, capacity, &cursor, data_i->len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int running_data_size = 0;
|
||||
for (int j = 0; j < FLX_PKT_MINIMUM_SIZE - FLX_PKT_MAXIMUM_SIZE - data_size; j++) {
|
||||
running_data_size += 1;
|
||||
out_buffer[FLX_PKT_MINIMUM_SIZE + data_size + j] = msg->data[i][j];
|
||||
|
||||
if (msg->data[i][j] == 0) break;
|
||||
for (int j = 0; j < data_i->len; j++) {
|
||||
if (!write_uint8(out_buffer, capacity, &cursor, data_i->ptr[j])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data_size += running_data_size;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
out_buffer[2] = data_size;
|
||||
result->size = FLX_PKT_MINIMUM_SIZE + data_size;
|
||||
result->reply = FLX_REPLY_VALID;
|
||||
return;
|
||||
int flx_deserialize(uint8_t *in_buffer, size_t capacity, struct flx_msg *msg) {
|
||||
size_t cursor = 0;
|
||||
|
||||
uint8_t action = 0;
|
||||
if (!read_uint8(in_buffer, capacity, &cursor, &action)) {
|
||||
return -1;
|
||||
}
|
||||
msg->action = action;
|
||||
|
||||
if (!read_uint8(in_buffer, capacity, &cursor, &msg->option)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void flx_deserialize(
|
||||
uint8_t in_buffer[FLX_PKT_MINIMUM_SIZE],
|
||||
struct flx_msg *msg,
|
||||
struct flx_serialize_result *result
|
||||
) {
|
||||
int valid_data_length = -1;
|
||||
int data_size_index = 0;
|
||||
int *data_sizes = NULL;
|
||||
int data_size = 0;
|
||||
int data_offset = FLX_PKT_MINIMUM_SIZE;
|
||||
flx_serialize_result_init(result);
|
||||
flx_msg_reset(msg);
|
||||
|
||||
if (in_buffer[0] <= LAST_ACTION_INDEX) {
|
||||
msg->action = in_buffer[0];
|
||||
valid_data_length = ACTION_SIZES[msg->action];
|
||||
} else {
|
||||
result->reply = FLX_REPLY_BAD_ACTION;
|
||||
return;
|
||||
if (!read_uint8(in_buffer, capacity, &cursor, &msg->data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in_buffer[1] > OPTION_RANGES[msg->action]) {
|
||||
result->reply = FLX_REPLY_BAD_OPTION;
|
||||
return;
|
||||
if (msg->data_len > FLX_DATA_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->option = in_buffer[1];
|
||||
for (int i = 0; i < msg->data_len; i++) {
|
||||
struct char_slice *data_i = &msg->data[i];
|
||||
|
||||
if (valid_data_length == 0) {
|
||||
if (in_buffer[2] != 0) {
|
||||
result->reply = FLX_REPLY_BAD_SIZE;
|
||||
return;
|
||||
} else {
|
||||
result->reply = FLX_REPLY_VALID;
|
||||
if (!read_uint8(in_buffer, capacity, &cursor, &data_i->len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return;
|
||||
data_i->ptr = (char *)read_uint8_array(in_buffer, capacity, &cursor, data_i->len);
|
||||
if (!data_i->ptr) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
msg->size = in_buffer[2];
|
||||
data_sizes = (int *)malloc(sizeof(int) * valid_data_length);
|
||||
|
||||
for (int i = FLX_PKT_MINIMUM_SIZE; i < FLX_PKT_MAXIMUM_SIZE; i++) {
|
||||
if (i > msg->size + FLX_PKT_MINIMUM_SIZE) {
|
||||
free(data_sizes);
|
||||
result->reply = FLX_REPLY_BAD_SIZE;
|
||||
return;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
if (data_size_index == valid_data_length) {
|
||||
if (data_size == 1) {
|
||||
free(data_sizes);
|
||||
result->reply = FLX_REPLY_BAD_SIZE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
int flx_write(int fd, struct flx_msg *msg) {
|
||||
uint8_t buffer[255];
|
||||
int msg_size = flx_serialize(buffer, sizeof(buffer), msg);
|
||||
if (msg_size < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in_buffer[i] == 0) {
|
||||
data_sizes[data_size_index] = ++data_size;
|
||||
data_size_index++;
|
||||
data_size = 0;
|
||||
continue;
|
||||
int written = 0;
|
||||
while (written < msg_size) {
|
||||
int result = write(fd, buffer + written, msg_size - written);
|
||||
if (result == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (result < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in_buffer[i] < '!' || in_buffer[i] > '~') {
|
||||
free(data_sizes);
|
||||
result->reply = FLX_REPLY_INVALID_DATA;
|
||||
return;
|
||||
written += result;
|
||||
}
|
||||
|
||||
data_size++;
|
||||
return msg_size;
|
||||
}
|
||||
|
||||
msg->data = (char**)malloc(sizeof(char *) * valid_data_length);
|
||||
msg->data_len = valid_data_length;
|
||||
|
||||
for (int i = 0; i < valid_data_length; i++) {
|
||||
msg->data[i] = (char *)malloc(sizeof(char) * data_sizes[i]);
|
||||
|
||||
for (int j = 0; j < data_sizes[i]; j++) {
|
||||
msg->data[i][j] = in_buffer[j + data_offset];
|
||||
int flx_read(uint8_t *buffer, size_t capacity, size_t *count, int fd, struct flx_msg *msg) {
|
||||
while (*count < capacity) {
|
||||
int result = read(fd, buffer + (*count), capacity - (*count));
|
||||
if (result == 0) {
|
||||
return 0;
|
||||
}
|
||||
data_offset += data_sizes[i];
|
||||
if (result <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->reply = FLX_REPLY_VALID;
|
||||
result->size = FLX_PKT_MINIMUM_SIZE + msg->size;
|
||||
free(data_sizes);
|
||||
return;
|
||||
(*count) += result;
|
||||
int msg_size = flx_deserialize(buffer, (*count), msg);
|
||||
if (msg_size > 0) {
|
||||
return msg_size;
|
||||
}
|
||||
|
||||
if (*count == capacity) {
|
||||
memmove(buffer, buffer+1, capacity-1);
|
||||
(*count)--;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *char_slice_dupe(struct char_slice slice) {
|
||||
char *str = calloc(slice.len + 1, sizeof(char));
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(str, slice.ptr, slice.len);
|
||||
return str;
|
||||
}
|
||||
|
@ -1,71 +1,74 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef uint8_t flx_act;
|
||||
typedef uint8_t flx_opt;
|
||||
|
||||
#define FLX_ACT_WATCH 0x00
|
||||
#define FLX_ACT_QUIT 0x01
|
||||
#define FLX_ACT_NOTIFY 0x02
|
||||
#define FLX_ACT_REPLY 0x03
|
||||
#define FLX_ACT_STATUS 0x04
|
||||
#define FLX_ACT_UNSET 0xFF
|
||||
enum flx_act {
|
||||
FLX_ACT_WATCH,
|
||||
FLX_ACT_QUIT,
|
||||
FLX_ACT_NOTIFY,
|
||||
FLX_ACT_STATUS,
|
||||
};
|
||||
|
||||
#define FLX_WATCH_ADD 0x00
|
||||
#define FLX_WATCH_REM 0x01
|
||||
enum flx_opt_watch {
|
||||
FLX_WATCH_ADD,
|
||||
FLX_WATCH_REM,
|
||||
};
|
||||
|
||||
#define FLX_QUIT_USER 0x00
|
||||
#define FLX_QUIT_ERROR 0x01
|
||||
enum flx_opt_quit {
|
||||
FLX_QUIT_USER,
|
||||
FLX_QUIT_ERROR,
|
||||
};
|
||||
|
||||
#define FLX_NOTIFY_CREATE 0x00
|
||||
#define FLX_NOTIFY_DELETE 0x01
|
||||
#define FLX_NOTIFY_ACCESS 0x02
|
||||
#define FLX_NOTIFY_CLOSE 0x03
|
||||
#define FLX_NOTIFY_MODIFY 0x04
|
||||
#define FLX_NOTIFY_MOVE 0x05
|
||||
enum flx_opt_notify {
|
||||
FLX_NOTIFY_CREATE,
|
||||
FLX_NOTIFY_DELETE,
|
||||
FLX_NOTIFY_ACCESS,
|
||||
FLX_NOTIFY_CLOSE,
|
||||
FLX_NOTIFY_MODIFY,
|
||||
FLX_NOTIFY_MOVE,
|
||||
};
|
||||
|
||||
#define FLX_REPLY_VALID 0x00
|
||||
#define FLX_REPLY_BAD_SIZE 0x01
|
||||
#define FLX_REPLY_BAD_ACTION 0x02
|
||||
#define FLX_REPLY_BAD_OPTION 0x03
|
||||
#define FLX_REPLY_BAD_PATH 0x04
|
||||
#define FLX_REPLY_INVALID_DATA 0x05
|
||||
#define FLX_REPLY_UNSET 0xFF
|
||||
enum flx_opt_status {
|
||||
FLX_STATUS_SUCCESS,
|
||||
FLX_STATUS_ERR_INIT_INOTIFY,
|
||||
FLX_STATUS_ERR_ADD_WATCH,
|
||||
FLX_STATUS_ERR_READ_INOTIFY,
|
||||
};
|
||||
|
||||
#define FLX_STATUS_SUCCESS 0x00
|
||||
#define FLX_STATUS_ERR_INIT_INOTIFY 0x01
|
||||
#define FLX_STATUS_ERR_ADD_WATCH 0x02
|
||||
#define FLX_STATUS_ERR_READ_INOTIFY 0x03
|
||||
enum flx_serialize_result {
|
||||
FLX_REPLY_VALID,
|
||||
FLX_REPLY_BAD_SIZE,
|
||||
FLX_REPLY_BAD_ACTION,
|
||||
FLX_REPLY_BAD_OPTION,
|
||||
FLX_REPLY_INVALID_DATA,
|
||||
};
|
||||
|
||||
#define FLX_UNSET_UNSET 0xFF
|
||||
|
||||
#define FLX_PKT_MINIMUM_SIZE 3
|
||||
#define FLX_PKT_MAXIMUM_SIZE 255
|
||||
|
||||
#define FLX_DLEN_WATCH 1
|
||||
#define FLX_DLEN_QUIT 0
|
||||
#define FLX_DLEN_NOTIFY 2
|
||||
#define FLX_DLEN_REPLY 0
|
||||
#define FLX_DLEN_STATUS 0
|
||||
#define FLX_DLEN_UNSET 0
|
||||
#define FLX_DATA_MAX 2
|
||||
|
||||
struct char_slice {
|
||||
const char *ptr;
|
||||
uint8_t len;
|
||||
};
|
||||
|
||||
struct flx_msg {
|
||||
flx_act action;
|
||||
enum flx_act action;
|
||||
flx_opt option;
|
||||
uint8_t size;
|
||||
|
||||
char **data;
|
||||
uint32_t data_len;
|
||||
struct char_slice data[FLX_DATA_MAX];
|
||||
uint8_t data_len;
|
||||
};
|
||||
|
||||
struct flx_serialize_result {
|
||||
int size;
|
||||
flx_opt reply;
|
||||
};
|
||||
void flx_msg_init_quit(struct flx_msg *msg, enum flx_opt_quit opt);
|
||||
void flx_msg_init_add_watch(struct flx_msg *msg, const char *filename);
|
||||
void flx_msg_init_remove_watch(struct flx_msg *msg, const char *filename);
|
||||
void flx_msg_init_notify(struct flx_msg *msg, enum flx_opt_notify opt, const char *base_path, const char *path);
|
||||
|
||||
void flx_serialize_result_init(struct flx_serialize_result *result);
|
||||
void flx_msg_init(struct flx_msg *msg);
|
||||
void flx_msg_free(struct flx_msg *msg);
|
||||
void flx_msg_reset(struct flx_msg *msg);
|
||||
void flx_serialize(uint8_t out_buffer[FLX_PKT_MAXIMUM_SIZE], struct flx_msg *msg, struct flx_serialize_result *result);
|
||||
void flx_deserialize(uint8_t in_buffer[FLX_PKT_MINIMUM_SIZE], struct flx_msg *msg, struct flx_serialize_result *result);
|
||||
int flx_serialize(uint8_t *out_buffer, size_t capacity, struct flx_msg *msg);
|
||||
int flx_deserialize(uint8_t *in_buffer, size_t capacity, struct flx_msg *msg);
|
||||
|
||||
int flx_write(int fd, struct flx_msg *msg);
|
||||
int flx_read(uint8_t *buffer, size_t capacity, size_t *count, int fd, struct flx_msg *msg);
|
||||
|
||||
char *char_slice_dupe(struct char_slice slice);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
@ -71,43 +72,33 @@ int main() {
|
||||
|
||||
printf("Accepted connection!\n");
|
||||
|
||||
struct flx_msg *read_msg = malloc(sizeof(struct flx_msg));
|
||||
struct flx_msg *send_msg = malloc(sizeof(struct flx_msg));
|
||||
struct flx_serialize_result result;
|
||||
char *path = NULL;
|
||||
|
||||
flx_msg_init(read_msg);
|
||||
flx_msg_init(send_msg);
|
||||
flx_serialize_result_init(&result);
|
||||
|
||||
uint8_t socket_buffer[FLX_PKT_MAXIMUM_SIZE];
|
||||
struct flx_msg read_msg = { 0 };
|
||||
uint8_t read_buffer[255] = { 0 };
|
||||
size_t read_buffer_size = 0;
|
||||
while (true) {
|
||||
int bytes_read = recv(client_fd, socket_buffer, sizeof(socket_buffer), 0);
|
||||
if (bytes_read == 0 || bytes_read == -1) {
|
||||
perror("recv");
|
||||
return -1;
|
||||
}
|
||||
|
||||
flx_deserialize(socket_buffer, read_msg, &result);
|
||||
if (result.reply != FLX_REPLY_VALID) {
|
||||
printf("Received error %x from client\n", result.reply);
|
||||
|
||||
send_msg->action = FLX_ACT_REPLY;
|
||||
send_msg->option = result.reply;
|
||||
send_msg = 0;
|
||||
|
||||
flx_serialize(socket_buffer, send_msg, &result);
|
||||
write(client_fd, socket_buffer, result.size);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_msg->action != FLX_ACT_WATCH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int msg_size = flx_read(read_buffer, sizeof(read_buffer), &read_buffer_size, client_fd, &read_msg);
|
||||
if (msg_size == 0) {
|
||||
break;
|
||||
}
|
||||
if (msg_size < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char *path = strdup(read_msg->data[0]);
|
||||
|
||||
if (read_msg.action == FLX_ACT_WATCH && read_msg.option == FLX_WATCH_ADD) {
|
||||
path = char_slice_dupe(read_msg.data[0]);
|
||||
assert(path != NULL);
|
||||
}
|
||||
|
||||
memmove(read_buffer, read_buffer + msg_size, sizeof(read_buffer) - msg_size);
|
||||
read_buffer_size -= msg_size;
|
||||
|
||||
if (path != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Watching path: %s\n", path);
|
||||
|
||||
@ -130,6 +121,7 @@ int main() {
|
||||
base_path += 1;
|
||||
}
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
@ -147,40 +139,46 @@ int main() {
|
||||
int buffer_used = 0;
|
||||
while (buffer_used < read_length) {
|
||||
struct inotify_event *event = (struct inotify_event*)&buffer[buffer_used];
|
||||
|
||||
if (event->mask & IN_CREATE) {
|
||||
send_msg->option = FLX_NOTIFY_CREATE;
|
||||
}
|
||||
if (event->mask & IN_DELETE) {
|
||||
send_msg->option = FLX_NOTIFY_DELETE;
|
||||
}
|
||||
if (event->mask & IN_ACCESS) {
|
||||
send_msg->option = FLX_NOTIFY_ACCESS;
|
||||
}
|
||||
if (event->mask & IN_CLOSE_WRITE) {
|
||||
send_msg->option = FLX_NOTIFY_CLOSE;
|
||||
}
|
||||
if (event->mask & IN_MODIFY) {
|
||||
send_msg->option = FLX_NOTIFY_MODIFY;
|
||||
}
|
||||
if (event->mask & IN_MOVE_SELF) {
|
||||
send_msg->option = FLX_NOTIFY_MOVE;
|
||||
}
|
||||
|
||||
buffer_used += sizeof(struct inotify_event) + event->len;
|
||||
|
||||
if (send_msg->option == FLX_UNSET_UNSET) {
|
||||
continue;
|
||||
struct flx_msg msg = { 0 };
|
||||
|
||||
if (event->mask & IN_CREATE) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_CREATE, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
if (event->mask & IN_DELETE) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_DELETE, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
if (event->mask & IN_ACCESS) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_ACCESS, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
if (event->mask & IN_CLOSE_WRITE) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_CLOSE, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
if (event->mask & IN_MODIFY) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_MODIFY, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
if (event->mask & IN_MOVE_SELF) {
|
||||
flx_msg_init_notify(&msg, FLX_NOTIFY_MOVE, base_path, path);
|
||||
if (flx_write(client_fd, &msg) <= 0) {
|
||||
g_state.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
send_msg->action = FLX_ACT_NOTIFY;
|
||||
send_msg->data_len = FLX_DLEN_NOTIFY;
|
||||
send_msg->data = malloc(sizeof(char*) * FLX_DLEN_NOTIFY);
|
||||
|
||||
send_msg->data[0] = base_path;
|
||||
send_msg->data[1] = path;
|
||||
|
||||
flx_serialize(socket_buffer, send_msg, &result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,20 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include <libflex.h>
|
||||
|
||||
#define PORT 12345
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (!notify_init("smartwatch")) {
|
||||
perror("notify_init");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
|
||||
return -1;
|
||||
@ -34,16 +41,61 @@ int main(int argc, char **argv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t payload_buffer[256];
|
||||
struct flex_byte_buffer bb = flex_bb_init(payload_buffer, sizeof(payload_buffer));
|
||||
flex_bb_push_buffer8(&bb, (uint8_t*)path, strlen(path));
|
||||
struct flx_msg msg = { 0 };
|
||||
flx_msg_init_add_watch(&msg, path);
|
||||
|
||||
uint8_t send_buffer[512];
|
||||
int send_size = flex_serialize(send_buffer, sizeof(send_buffer), 1, bb.data, bb.size);
|
||||
|
||||
write(client_fd, send_buffer, send_size);
|
||||
int rc = flx_write(client_fd, &msg);
|
||||
assert(rc > 0);
|
||||
|
||||
struct flx_msg read_msg = { 0 };
|
||||
uint8_t read_buffer[255] = { 0 };
|
||||
size_t read_buffer_size = 0;
|
||||
while (true) {
|
||||
int msg_size = flx_read(read_buffer, sizeof(read_buffer), &read_buffer_size, client_fd, &read_msg);
|
||||
if (msg_size == 0) {
|
||||
break;
|
||||
}
|
||||
if (msg_size < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_msg.action == FLX_ACT_NOTIFY) {
|
||||
const char *notify_message = "Unknown.\n";
|
||||
switch (read_msg.option) {
|
||||
case FLX_NOTIFY_CREATE:
|
||||
notify_message = "File created.\n";
|
||||
break;
|
||||
case FLX_NOTIFY_DELETE:
|
||||
notify_message = "File deleted.\n";
|
||||
break;
|
||||
case FLX_NOTIFY_ACCESS:
|
||||
notify_message = "File accessed.\n";
|
||||
break;
|
||||
case FLX_NOTIFY_CLOSE:
|
||||
notify_message = "File written and closed.\n";
|
||||
break;
|
||||
case FLX_NOTIFY_MODIFY:
|
||||
notify_message = "File modified.\n";
|
||||
break;
|
||||
case FLX_NOTIFY_MOVE:
|
||||
notify_message = "File moved.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
char *base_path = char_slice_dupe(read_msg.data[0]);
|
||||
assert(base_path != NULL);
|
||||
|
||||
NotifyNotification *notification = notify_notification_new(base_path, notify_message, "dialog-information");
|
||||
assert(notification != NULL);
|
||||
|
||||
notify_notification_set_urgency(notification, NOTIFY_URGENCY_CRITICAL);
|
||||
notify_notification_show(notification, NULL);
|
||||
g_object_unref(G_OBJECT(notification));
|
||||
free(base_path);
|
||||
}
|
||||
|
||||
memmove(read_buffer, read_buffer + msg_size, sizeof(read_buffer) - msg_size);
|
||||
read_buffer_size -= msg_size;
|
||||
}
|
||||
|
||||
close(client_fd);
|
||||
|
Loading…
Reference in New Issue
Block a user