diff --git a/src/cnadd.c b/src/cnadd.c index c1dca06..08692b6 100644 --- a/src/cnadd.c +++ b/src/cnadd.c @@ -7,6 +7,11 @@ #include "platform.h" #include "config.h" +/** + * @brief Ensures that the directory at the given path exists, creating it if necessary. + * @param path The path to the directory. + * @return 1 if the directory exists or was created successfully, 0 otherwise. + */ int ensure_directory_exists(const char *path) { struct stat st; @@ -37,6 +42,12 @@ int ensure_directory_exists(const char *path) { return 1; } +/** + * @brief Retrieves the path to the cnotes directory, using environment variables if set. + * @param buffer Buffer to store the path. + * @param bufsize Size of the buffer. + * @return 1 if the path was successfully retrieved, 0 otherwise. + */ int get_cnotes_path(char *buffer, size_t bufsize) { const char *custom_path; const char *home; @@ -81,6 +92,12 @@ int get_cnotes_path(char *buffer, size_t bufsize) { return 1; } +/** + * @brief Writes a new entry to the cnotes file with the given category and message. + * @param category The category for the entry (max 10 characters). + * @param message The message text (max 80 characters). + * @return 1 if the entry was written successfully, 0 otherwise. + */ int write_entry(const char *category, const char *message) { char dir_path[512]; char file_path[600]; @@ -154,6 +171,10 @@ int write_entry(const char *category, const char *message) { return 1; } +/** + * @brief Prints the usage information for the program. + * @param prog_name The name of the program. + */ void print_usage(const char *prog_name) { fprintf(stderr, "Usage: %s [-c category] message\n", prog_name); fprintf(stderr, " -c category Optional category (max 10 chars, default: %s)\n", @@ -161,6 +182,12 @@ void print_usage(const char *prog_name) { fprintf(stderr, " message Required message text (max 80 chars). Wrapped in double-quotes.\n"); } +/** + * @brief Main entry point of the program. + * @param argc Number of command-line arguments. + * @param argv Array of command-line arguments. + * @return 0 on success, 1 on failure. + */ int main(int argc, char *argv[]) { const char *category; const char *message; @@ -200,4 +227,4 @@ int main(int argc, char *argv[]) { } return 0; -} +} \ No newline at end of file diff --git a/src/cnadd.c.bak b/src/cnadd.c.bak new file mode 100644 index 0000000..32a3d03 --- /dev/null +++ b/src/cnadd.c.bak @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include + +#include "platform.h" +#include "config.h" + +int ensure_directory_exists(const char *path) { + struct stat st; + + if (stat(path, &st) == 0) { + /* Path exists, check if it's a directory */ + if (S_ISDIR(st.st_mode)) { + return 1; + } else { + fprintf(stderr, "Error: %s exists but is not a directory\n", path); + return 0; + } + } + + /* Directory doesn't exist, try to create it */ + if (mkdir_portable(path) != 0) { + fprintf(stderr, "Error: Cannot create directory %s\n", path); + return 0; + } + return 1; +} + +int get_cnotes_path(char *buffer, size_t bufsize) { + const char *custom_path; + const char *home; + size_t len; + + /* First check for CNOTES_PATH environment variable override */ + custom_path = getenv(CNOTES_PATH_ENV); + if (custom_path != NULL && strlen(custom_path) > 0) { + if (strlen(custom_path) >= bufsize) { + fprintf(stderr, "Error: Path too long\n"); + return 0; + } + strcpy(buffer, custom_path); + return 1; + } + + /* Fall back to HOME_ENV + CNOTES_DIR */ + home = getenv(HOME_ENV); + if (home == NULL) { + fprintf(stderr, "Error: %s environment variable not set\n", HOME_ENV); + fprintf(stderr, "Hint: Set %s to specify notes directory\n", CNOTES_PATH_ENV); + return 0; + } + + /* Build path: $HOME/CNOTES_DIR (or just $HOME if CNOTES_DIR is empty) */ + len = strlen(home); + if (strlen(CNOTES_DIR) == 0) { + /* DOS mode: use home directory directly */ + if (len >= bufsize) { + fprintf(stderr, "Error: Path too long\n"); + return 0; + } + strcpy(buffer, home); + } else { + /* Unix/Windows: append CNOTES_DIR to home */ + if (len + strlen(CNOTES_DIR) + 2 > bufsize) { + fprintf(stderr, "Error: Path too long\n"); + return 0; + } + sprintf(buffer, "%s" PATH_SEP_STR "%s", home, CNOTES_DIR); + } + return 1; +} + +int write_entry(const char *category, const char *message) { + char dir_path[512]; + char file_path[600]; + FILE *file; + time_t now; + struct tm *tm_info; + char date[11]; + char time_str[6]; + char padded_category[CATEGORY_LENGTH + 1]; + char truncated_message[FREETEXT_MAX_LENGTH + 1]; + int i; + + /* Get current date and time */ + now = time(NULL); + if (now == -1) { + fprintf(stderr, "Error: Cannot get current time\n"); + return 0; + } + + tm_info = localtime(&now); + if (tm_info == NULL) { + fprintf(stderr, "Error: Cannot convert time\n"); + return 0; + } + + /* Format date as YYYY-MM-DD */ + strftime(date, sizeof(date), "%Y-%m-%d", tm_info); + + /* Format time as HH:MM */ + strftime(time_str, sizeof(time_str), "%H:%M", tm_info); + + /* Pad category to 10 characters */ + strncpy(padded_category, category, CATEGORY_LENGTH); + padded_category[CATEGORY_LENGTH] = '\0'; + for (i = (int)strlen(padded_category); i < CATEGORY_LENGTH; i++) { + padded_category[i] = ' '; + } + padded_category[CATEGORY_LENGTH] = '\0'; + + /* Truncate message to 80 characters */ + strncpy(truncated_message, message, FREETEXT_MAX_LENGTH); + truncated_message[FREETEXT_MAX_LENGTH] = '\0'; + + /* Get cnotes directory path */ + if (!get_cnotes_path(dir_path, sizeof(dir_path))) { + return 0; + } + + /* Ensure directory exists */ + if (!ensure_directory_exists(dir_path)) { + return 0; + } + + /* Build full file path */ + sprintf(file_path, "%s" PATH_SEP_STR "%s", dir_path, CNOTES_FILE); + + /* Open file in append mode */ + file = fopen(file_path, "a"); + if (file == NULL) { + fprintf(stderr, "Error: Cannot open file %s\n", file_path); + return 0; + } + + /* Write entry */ + fprintf(file, "%s,%s,%s,\"%s\"\n", + date, time_str, padded_category, truncated_message); + + fclose(file); + + printf("Entry added to %s\n", file_path); + return 1; +} + +void print_usage(const char *prog_name) { + fprintf(stderr, "Usage: %s [-c category] message\n", prog_name); + fprintf(stderr, " -c category Optional category (max 10 chars, default: %s)\n", + DEFAULT_CATEGORY); + fprintf(stderr, " message Required message text (max 80 chars). Wrapped in double-quotes.\n"); +} + +int main(int argc, char *argv[]) { + const char *category; + const char *message; + int i; + + category = DEFAULT_CATEGORY; + message = NULL; + + /* Parse command-line arguments */ + i = 1; + while (i < argc) { + if (strcmp(argv[i], "-c") == 0) { + if (i + 1 >= argc) { + fprintf(stderr, "Error: -c option requires an argument\n"); + print_usage(argv[0]); + return 1; + } + category = argv[i + 1]; + i += 2; + } else { + message = argv[i]; + i++; + break; /* Only take first non-option as message */ + } + } + + /* Validate arguments */ + if (message == NULL || strlen(message) == 0) { + fprintf(stderr, "Error: Message is required\n"); + print_usage(argv[0]); + return 1; + } + + /* Write entry */ + if (!write_entry(category, message)) { + return 1; + } + + return 0; +}