diff --git a/capsule-core/src/main.zig b/capsule-core/src/main.zig index 75da307..fe0c4f7 100644 --- a/capsule-core/src/main.zig +++ b/capsule-core/src/main.zig @@ -178,9 +178,20 @@ fn printUsage() void { } fn runDaemon(allocator: std.mem.Allocator, port_override: ?u16, data_dir_override: ?[]const u8) !void { - // Load Config - // Check for config.json, otherwise use default - const config_path = "config.json"; + // Determine data directory + const data_dir = data_dir_override orelse "data"; + + // Create data directory if it doesn't exist + std.fs.cwd().makeDir(data_dir) catch |err| { + if (err != error.PathAlreadyExists) { + std.log.err("Failed to create data directory {s}: {}", .{data_dir, err}); + return err; + } + }; + + // Load Config from data directory + const config_path = try std.fs.path.join(allocator, &[_][]const u8{ data_dir, "config.json" }); + defer allocator.free(config_path); var config = config_mod.NodeConfig.loadFromJsonFile(allocator, config_path) catch |err| { if (err == error.FileNotFound) { std.log.info("Config missing, using defaults", .{}); @@ -189,6 +200,11 @@ fn runDaemon(allocator: std.mem.Allocator, port_override: ?u16, data_dir_overrid if (data_dir_override) |d| { allocator.free(cfg.data_dir); cfg.data_dir = try allocator.dupe(u8, d); + // Regenerate socket and key paths based on new data_dir + allocator.free(cfg.control_socket_path); + cfg.control_socket_path = try std.fmt.allocPrint(allocator, "{s}/capsule.sock", .{d}); + allocator.free(cfg.identity_key_path); + cfg.identity_key_path = try std.fmt.allocPrint(allocator, "{s}/identity.key", .{d}); } const node = try node_mod.CapsuleNode.init(allocator, cfg); defer node.deinit(); @@ -205,6 +221,11 @@ fn runDaemon(allocator: std.mem.Allocator, port_override: ?u16, data_dir_overrid if (data_dir_override) |d| { allocator.free(config.data_dir); config.data_dir = try allocator.dupe(u8, d); + // Regenerate socket and key paths based on new data_dir + allocator.free(config.control_socket_path); + config.control_socket_path = try std.fmt.allocPrint(allocator, "{s}/capsule.sock", .{d}); + allocator.free(config.identity_key_path); + config.identity_key_path = try std.fmt.allocPrint(allocator, "{s}/identity.key", .{d}); } // Initialize Node @@ -216,15 +237,18 @@ fn runDaemon(allocator: std.mem.Allocator, port_override: ?u16, data_dir_overrid } fn runCliCommand(allocator: std.mem.Allocator, cmd: control_mod.Command, data_dir_override: ?[]const u8) !void { - // Load config to find socket path - const config_path = "config.json"; + // Determine data directory + const data_dir = data_dir_override orelse "data"; + + // Load config from data directory + const config_path = try std.fs.path.join(allocator, &[_][]const u8{ data_dir, "config.json" }); + defer allocator.free(config_path); var config = config_mod.NodeConfig.loadFromJsonFile(allocator, config_path) catch { std.log.err("Failed to load config to find control socket. Is config.json present?", .{}); return error.ConfigLoadFailed; }; defer config.deinit(allocator); - const data_dir = data_dir_override orelse config.data_dir; const socket_path = if (std.fs.path.isAbsolute(config.control_socket_path)) try allocator.dupe(u8, config.control_socket_path) else