diff options
author | Aaron Ball <nullspoon@oper.io> | 2022-04-14 17:48:15 -0600 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2022-04-14 17:48:15 -0600 |
commit | 9c8ca4daaaa6a163cbb559643254e6404be8bcd3 (patch) | |
tree | 29084ec84c3ad7be231ce67301a929d4377ac413 /src | |
download | dailyjournal-9c8ca4daaaa6a163cbb559643254e6404be8bcd3.tar.gz dailyjournal-9c8ca4daaaa6a163cbb559643254e6404be8bcd3.tar.xz |
Initial commit of source, readme, template, and license
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..faf8a9e --- /dev/null +++ b/src/main.c @@ -0,0 +1,152 @@ +/** + * Dailyjournal is an easy tool to log daily activities + * Copyright (C) 2022 Aaron Ball <nullspoon@oper.io> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#define _XOPEN_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define DEFAULT_EXTENSION ".md" + +void get_user_editor(char* editor) { + if(getenv("EDITOR") != NULL) + strcpy(editor, getenv("EDITOR")); + else + strcpy(editor, "vi"); +} + +int fedit(char* path) { + char editor[256]; + char cmd[512]; + get_user_editor(editor); + sprintf(cmd, "%s %s", editor, path); + return system(cmd); +} + +int fexists(char* path) { + FILE* fd = fopen(path, "r"); + if(!fd) + return 0; + fclose(fd); + return 1; +} + +int safe_cp(char* src, char* dest) { + FILE* fdsrc = NULL; + FILE* fddest = NULL; + char c = '\0'; + + fdsrc = fopen(src, "r"); + if(!fdsrc) + return -2; + + // Open destination file for appending, juuuuust in case it already exists + fddest = fopen(dest, "r"); + if(fddest) { + fclose(fddest); + fclose(fdsrc); + return 0; + } + + fddest = fopen(dest, "a+"); + if(! fddest) + return -2; + + while((c = fgetc(fdsrc)) != EOF) + fputc(c, fddest); + + fclose(fdsrc); + fclose(fddest); + return 0; +} + +void getpath(char* base, int days, char* out, char* extension) { + time_t t; + struct tm* tmnow; + char filename[128]; + + t = time(NULL); + t = t + (days * 86400); + tmnow = localtime(&t); + + strftime(filename, 256, "%F", tmnow); + + sprintf(out, "%s/%s%s", base, filename, extension); +} + +int env_or_default(char* buf, char* varname, char* defaultval) { + char* env = getenv(varname); + if(env == NULL) { + sprintf(buf, "%s", defaultval); + return 1; + } + sprintf(buf, "%s", env); + return 0; +} + +int main(int argc, char* argv[]) { + char notepath[256] = {'\0'}; + char journaldir[512] = {'\0'}; + char templatepath[512] = {'\0'}; + char *extension = NULL; + int i = 0; + + // Set default paths + sprintf(journaldir, "%s/%s", getenv("HOME"), "Documents/dailyjournal"); + + int days = 0; + if(argc > 1) + days = strtol(argv[1], NULL, 10); + + // Set default values + env_or_default(journaldir, "DAILYJOURNAL_DIR", journaldir); + sprintf(templatepath, "%s/.template.md", journaldir); + env_or_default(templatepath, "DAILYJOURNAL_TEMPLATE", templatepath); + + extension = strrchr(templatepath, '.'); + if(!extension) + extension = DEFAULT_EXTENSION; + + // If user requests negative days, we want to skip non-existant days. So `-2` + // is really "two entries ago" rather than two days ago, which could yield + // creating an empty historical note if one does not already exist (for + // example: on Monday, opening Friday's entry which is -3 days, but -1 + // entry). + if(days < 0) { + while(days < 0) { + i--; + getpath(journaldir, i, notepath, extension); + if(fexists(notepath)) + days++; + // Stop traversing after a year to avoid infinite loops when no notes + // exist (or exist very long ago) + if(i < -365) { + fprintf(stderr, "Refusing to search further back than one year\n"); + return 1; + } + } + } else { + getpath(journaldir, days, notepath, extension); + } + + if(safe_cp(templatepath, notepath) == -2) { + printf("No template found at %s\n", templatepath); + return 2; + } + return fedit(notepath); +} |