initial commit
This commit is contained in:
commit
bf4c7f8f5e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
zig-cache
|
||||||
|
zig-out
|
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Over engineered custom network protocol experiment
|
||||||
|
|
||||||
|
Youtube tutorial: https://www.youtube.com/watch?v=AS_nxNS6YKY
|
||||||
|
|
82
build.zig
Normal file
82
build.zig
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
fn linkPkgConfigOutput(b: *std.build.Builder, obj: *std.build.LibExeObjStep, 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(.{
|
||||||
|
.allocator = b.allocator,
|
||||||
|
.argv = argv.items
|
||||||
|
});
|
||||||
|
|
||||||
|
const stdout_trimmed = std.mem.trim(u8, result.stdout, " \n");
|
||||||
|
var cflags_iter = std.mem.splitScalar(u8, stdout_trimmed, ' ');
|
||||||
|
while (cflags_iter.next()) |cflag| {
|
||||||
|
if (std.mem.startsWith(u8, cflag, "-l")) {
|
||||||
|
obj.linkSystemLibrary(cflag[2..]);
|
||||||
|
} else if (std.mem.startsWith(u8, cflag, "-I")) {
|
||||||
|
obj.addIncludePath(.{ .path = cflag[2..] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(b: *std.build.Builder) !void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const libflex = b.addStaticLibrary(.{
|
||||||
|
.name = "flex",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
libflex.addCSourceFile(.{
|
||||||
|
.file = .{ .path = "libflex/libflex.c" },
|
||||||
|
.flags = &.{}
|
||||||
|
});
|
||||||
|
libflex.linkLibC();
|
||||||
|
libflex.installHeader("libflex/libflex.h", "libflex.h");
|
||||||
|
|
||||||
|
{
|
||||||
|
const rolexhound = b.addExecutable(.{
|
||||||
|
.name = "rolexhound",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.root_source_file = .{ .path = "rolexhound/main.c" }
|
||||||
|
});
|
||||||
|
rolexhound.linkLibrary(libflex);
|
||||||
|
rolexhound.linkLibC();
|
||||||
|
try linkPkgConfigOutput(b, rolexhound, &.{ "--cflags", "--libs", "libnotify" });
|
||||||
|
|
||||||
|
b.installArtifact(rolexhound);
|
||||||
|
|
||||||
|
const run_rolexhound = b.addRunArtifact(rolexhound);
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_rolexhound.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("rolexhound", "Run the server");
|
||||||
|
run_step.dependOn(&run_rolexhound.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const smartwatch = b.addExecutable(.{
|
||||||
|
.name = "smartwatch",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.root_source_file = .{ .path = "smartwatch/main.c" }
|
||||||
|
});
|
||||||
|
smartwatch.linkLibrary(libflex);
|
||||||
|
smartwatch.linkLibC();
|
||||||
|
|
||||||
|
b.installArtifact(smartwatch);
|
||||||
|
|
||||||
|
const run_smartwatch = b.addRunArtifact(smartwatch);
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_smartwatch.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("smartwatch", "Run the client");
|
||||||
|
run_step.dependOn(&run_smartwatch.step);
|
||||||
|
}
|
||||||
|
}
|
14
compile_flags.txt
Normal file
14
compile_flags.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-Ilibflex/
|
||||||
|
-I/usr/include/gdk-pixbuf-2.0
|
||||||
|
-I/usr/include/glib-2.0
|
||||||
|
-I/usr/lib/glib-2.0/include
|
||||||
|
-I/usr/include/blkid
|
||||||
|
-I/usr/include/libmount
|
||||||
|
-I/usr/include/sysprof-6
|
||||||
|
-pthread
|
||||||
|
-I/usr/include/libpng16
|
||||||
|
-lnotify
|
||||||
|
-lgdk_pixbuf-2.0
|
||||||
|
-lgio-2.0
|
||||||
|
-lgobject-2.0
|
||||||
|
-lglib-2.0
|
206
libflex/libflex.c
Normal file
206
libflex/libflex.c
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.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(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_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_reset(struct flx_msg *msg) {
|
||||||
|
flx_msg_free(msg);
|
||||||
|
flx_msg_init(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_data_length != msg->data_len) {
|
||||||
|
result->reply = FLX_REPLY_BAD_SIZE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->option > OPTION_RANGES[msg->option]) {
|
||||||
|
result->reply = FLX_REPLY_BAD_OPTION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buffer[1] = msg->option;
|
||||||
|
|
||||||
|
if (valid_data_length != 0 && msg->data == NULL) {
|
||||||
|
result->reply = FLX_REPLY_INVALID_DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < msg->data_len; i++) {
|
||||||
|
if (msg->data[i] == NULL) {
|
||||||
|
result->reply = FLX_REPLY_INVALID_DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_size += running_data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buffer[2] = data_size;
|
||||||
|
result->size = FLX_PKT_MINIMUM_SIZE + data_size;
|
||||||
|
result->reply = FLX_REPLY_VALID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (in_buffer[1] > OPTION_RANGES[msg->action]) {
|
||||||
|
result->reply = FLX_REPLY_BAD_OPTION;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->option = in_buffer[1];
|
||||||
|
|
||||||
|
if (valid_data_length == 0) {
|
||||||
|
if (in_buffer[2] != 0) {
|
||||||
|
result->reply = FLX_REPLY_BAD_SIZE;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
result->reply = FLX_REPLY_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_size_index == valid_data_length) {
|
||||||
|
if (data_size == 1) {
|
||||||
|
free(data_sizes);
|
||||||
|
result->reply = FLX_REPLY_BAD_SIZE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_buffer[i] == 0) {
|
||||||
|
data_sizes[data_size_index] = ++data_size;
|
||||||
|
data_size_index++;
|
||||||
|
data_size = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_buffer[i] < '!' || in_buffer[i] > '~') {
|
||||||
|
free(data_sizes);
|
||||||
|
result->reply = FLX_REPLY_INVALID_DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_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];
|
||||||
|
}
|
||||||
|
data_offset += data_sizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
result->reply = FLX_REPLY_VALID;
|
||||||
|
result->size = FLX_PKT_MINIMUM_SIZE + msg->size;
|
||||||
|
free(data_sizes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
71
libflex/libflex.h
Normal file
71
libflex/libflex.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include <stdint.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
|
||||||
|
|
||||||
|
#define FLX_WATCH_ADD 0x00
|
||||||
|
#define FLX_WATCH_REM 0x01
|
||||||
|
|
||||||
|
#define FLX_QUIT_USER 0x00
|
||||||
|
#define FLX_QUIT_ERROR 0x01
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
struct flx_msg {
|
||||||
|
flx_act action;
|
||||||
|
flx_opt option;
|
||||||
|
uint8_t size;
|
||||||
|
|
||||||
|
char **data;
|
||||||
|
uint32_t data_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct flx_serialize_result {
|
||||||
|
int size;
|
||||||
|
flx_opt reply;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
190
rolexhound/main.c
Normal file
190
rolexhound/main.c
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <libflex.h>
|
||||||
|
|
||||||
|
struct daemon_state {
|
||||||
|
bool running;
|
||||||
|
int inotify_fd;
|
||||||
|
int inotify_wd;
|
||||||
|
};
|
||||||
|
static struct daemon_state g_state = {
|
||||||
|
.running = true
|
||||||
|
};
|
||||||
|
|
||||||
|
void daemon_deinit(struct daemon_state *state) {
|
||||||
|
inotify_rm_watch(g_state.inotify_fd, g_state.inotify_wd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_handler(int signal) {
|
||||||
|
g_state.running = false;
|
||||||
|
printf("Stoping daemon\n");
|
||||||
|
daemon_deinit(&g_state);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PORT 12345
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_fd == -1) {
|
||||||
|
perror("socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int on = 1;
|
||||||
|
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
|
||||||
|
perror("bind");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(server_fd, 1) == -1) {
|
||||||
|
perror("listen");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("listening on 0.0.0.0:%d...\n", PORT);
|
||||||
|
|
||||||
|
struct sockaddr_storage client_addr;
|
||||||
|
socklen_t client_addrlen;
|
||||||
|
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_addrlen);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
perror("accept");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
flx_msg_init(read_msg);
|
||||||
|
flx_msg_init(send_msg);
|
||||||
|
flx_serialize_result_init(&result);
|
||||||
|
|
||||||
|
uint8_t socket_buffer[FLX_PKT_MAXIMUM_SIZE];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *path = strdup(read_msg->data[0]);
|
||||||
|
|
||||||
|
printf("Watching path: %s\n", path);
|
||||||
|
|
||||||
|
int inotify_fd = inotify_init();
|
||||||
|
if (inotify_fd == -1) {
|
||||||
|
perror("inotify_init");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inotify_wd = inotify_add_watch(inotify_fd, path, IN_CREATE | IN_DELETE | IN_ACCESS | IN_CLOSE_WRITE | IN_MODIFY | IN_MOVE_SELF);
|
||||||
|
if (inotify_fd == -1) {
|
||||||
|
perror("inotify_add_watch");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *base_path = strrchr(path, '/');
|
||||||
|
if (base_path == NULL) {
|
||||||
|
base_path = path;
|
||||||
|
} else {
|
||||||
|
base_path += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGABRT, signal_handler);
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
|
||||||
|
uint8_t buffer[4096];
|
||||||
|
while (g_state.running) {
|
||||||
|
printf("Waiting for inotify event.\n");
|
||||||
|
|
||||||
|
int read_length = read(inotify_fd, buffer, sizeof(buffer));
|
||||||
|
if (read_length == -1) {
|
||||||
|
perror("read");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
daemon_deinit(&g_state);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
52
smartwatch/main.c
Normal file
52
smartwatch/main.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libflex.h>
|
||||||
|
|
||||||
|
#define PORT 12345
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *path = argv[1];
|
||||||
|
|
||||||
|
int client_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (client_fd == -1) {
|
||||||
|
perror("socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
server_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
|
||||||
|
perror("connect");
|
||||||
|
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));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
close(client_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user