diff --git a/examples/print_info.c b/examples/print_info.c index 8064828..ad470bc 100644 --- a/examples/print_info.c +++ b/examples/print_info.c @@ -53,12 +53,20 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } + UnixFsDriverData driver_data = { path }; + + int max_id = unix_fs_driver_get_max_id(&driver_data); + if (max_id <= 0) { + fprintf(stderr, "Warning: failed to get id of last comment\n"); + } else if (id >= max_id) { + fprintf(stderr, "Last comment has id %d, which is less than %d\n", max_id - 1, id); + exit(EXIT_FAILURE); + } + CommentHeader *header = malloc(sizeof(CommentHeader)); header->user_sid = malloc(BUF_SZ); header->user_displayname = malloc(BUF_SZ); - UnixFsDriverData driver_data = { path }; - if (driver->get_header(&driver_data, header, id) < 0) { fprintf(stderr, "failed to get header of comment, are you sure it exists?\n"); exit(EXIT_FAILURE); diff --git a/include/drivers/unix_fs/unix_fs_driver.h b/include/drivers/unix_fs/unix_fs_driver.h index ed3799f..740ac2e 100644 --- a/include/drivers/unix_fs/unix_fs_driver.h +++ b/include/drivers/unix_fs/unix_fs_driver.h @@ -12,11 +12,12 @@ typedef struct { } UnixFsDriverData; int unix_fs_driver_leave_comment(void *driver_data_ptr, const CommentHeader *header, const char *text); - int unix_fs_driver_get_header(void *driver_data_ptr, CommentHeader *header, int id); - int unix_fs_driver_get_text(void *driver_data_ptr, char *text, int id); static const Driver unix_fs_driver = { unix_fs_driver_leave_comment, unix_fs_driver_get_header, unix_fs_driver_get_text }; +int unix_fs_driver_get_max_id(void *driver_data_ptr); + + #endif /* UNIX_FS_DRIVER_H */ diff --git a/src/drivers/unix_fs/unix_fs_driver.c b/src/drivers/unix_fs/unix_fs_driver.c index 860be61..208c0a4 100644 --- a/src/drivers/unix_fs/unix_fs_driver.c +++ b/src/drivers/unix_fs/unix_fs_driver.c @@ -16,15 +16,22 @@ #define READ_BUF_SZ 256 -#define SWRITE(fd, buf, count) \ +#define SWRITE(fd, buf, count) do { \ if (write(fd, buf, count) < count) { \ return -EINVAL; \ - } + } \ +} while(0); -#define SREAD(fd, buf, count) \ +#define SREAD(fd, buf, count) do { \ if (read(fd, buf, count) < count) { \ return -EINVAL; \ - } + } \ +} while (0); + +#define NOLCK_ABORT() do { \ + fprintf(stderr, "Failed to release id control file, aborting...\n"); \ + abort(); \ +} while (0); int is_valid_directory(const char *path) @@ -121,6 +128,43 @@ release_id_ctrl_file(FILE *id_ctrl_file) return fclose(id_ctrl_file); } +int +unix_fs_driver_get_max_id(void *driver_data_ptr) +{ + char *path, *id_ctrl_file_path; + FILE *id_ctrl_file; + int retval; + + path = ((UnixFsDriverData*) driver_data_ptr)->path; + + id_ctrl_file_path = NULL; + id_ctrl_file = NULL; + + if (asprintf(&id_ctrl_file_path, "%s/%s", path, ID_CTRL_FILE) < 0) { + id_ctrl_file_path = NULL; + retval = -ENOMEM; + goto defer; + } + + if (!(id_ctrl_file = acquire_id_ctrl_file(id_ctrl_file_path))) { + retval = -EIO; + goto defer; + } + + if (fscanf(id_ctrl_file, "%d", &retval) < 1) { + retval = -EIO; + goto defer; + } +defer: + if (id_ctrl_file) { + if (release_id_ctrl_file(id_ctrl_file) < 0) { + NOLCK_ABORT(); + } + } + free(id_ctrl_file_path); + return retval; +} + int unix_fs_driver_leave_comment(void *driver_data_ptr, const CommentHeader *header, const char *text) { @@ -196,8 +240,7 @@ unix_fs_driver_leave_comment(void *driver_data_ptr, const CommentHeader *header, defer: if (id_ctrl_file) { if (release_id_ctrl_file(id_ctrl_file) < 0) { - fprintf(stderr, "Failed to release id control file, aborting...\n"); - abort(); + NOLCK_ABORT(); } } free(id_ctrl_file_path);