cnotes/addnote.c

179 lines
4.6 KiB
C
Raw Normal View History

2025-10-04 13:54:38 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "platform.h"
#define CATEGORY_LENGTH 10
#define FREETEXT_MAX_LENGTH 80
#define DEFAULT_CATEGORY "General"
#define CNOTES_DIR ".local/share/cnotes"
#define CNOTES_FILE "cnotes.csv"
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 *home;
size_t len;
home = getenv("HOME");
if (home == NULL) {
fprintf(stderr, "Error: HOME environment variable not set\n");
return 0;
}
/* Build path: $HOME/.local/share/cnotes */
len = strlen(home);
if (len + strlen(CNOTES_DIR) + 2 > bufsize) {
fprintf(stderr, "Error: Path too long\n");
return 0;
}
sprintf(buffer, "%s/%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/%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 {
/* This is the message */
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;
}