commit 7265315d86624fcf1cc1dcc4ddf6da2a500aea8d
parent ae94c615a96576e137e9c2db74ddcafe35f70643
Author: in0rdr <andreas.gruhler@uzh.ch>
Date: Thu, 24 Nov 2016 01:13:20 +0800
Improves (file) path handling, reading and writing
Diffstat:
M | diary.c | | | 158 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 109 insertions(+), 49 deletions(-)
diff --git a/diary.c b/diary.c
@@ -23,7 +23,9 @@ struct tm cal_end;
static const char* WEEKDAYS[] = {"Mo","Tu","We","Th","Fr","Sa","Su", NULL};
-void get_date_str(struct tm* date, char* date_str, int date_str_size) {
+void fpath(char* dir, size_t dir_size, struct tm* date, char* rpath, size_t rpath_size);
+
+void get_date_str(struct tm* date, char* date_str, size_t date_str_size) {
strftime(date_str, date_str_size, "%Y-%m-%d", date);
}
@@ -36,21 +38,28 @@ void draw_wdays(WINDOW* head) {
wrefresh(head);
}
-void draw_calendar(WINDOW* number_pad, WINDOW* month_pad, char* diary_dir) {
+void draw_calendar(WINDOW* number_pad, WINDOW* month_pad, char* diary_dir, size_t diary_dir_size) {
struct tm i = cal_start;
char month[10];
+ char epath[100];
bool has_entry;
while (mktime(&i) <= mktime(&cal_end)) {
- has_entry = access(fpath(dirary_dir, &i), F_OK) != -1);
- getyx(number_pad, cy, cx);
+ // get entry path and check for existence
+ fpath(diary_dir, diary_dir_size, &i, epath, sizeof epath);
+ has_entry = (access(epath, F_OK) != -1);
+
if (has_entry)
wattron(number_pad, A_BOLD);
+
wprintw(number_pad, "%2i", i.tm_mday);
+
if (has_entry)
wattroff(number_pad, A_BOLD);
+
waddch(number_pad, ' ');
+ // print month in sidebar
if (i.tm_mday == 1) {
strftime(month, sizeof month, "%b", &i);
getyx(number_pad, cy, cx);
@@ -65,38 +74,71 @@ void draw_calendar(WINDOW* number_pad, WINDOW* month_pad, char* diary_dir) {
void update_date(WINDOW* dh) {
char dstr[16];
mktime(&curs_date);
- get_date_str(&curs_date, dstr, sizeof(dstr));
+ get_date_str(&curs_date, dstr, sizeof dstr);
mvwaddstr(dh, 0, 0, dstr);
wrefresh(dh);
}
-char* fpath(char* dir, struct tm* date) {
- char path[100];
- char dstr[16];
+void fpath(char* dir, size_t dir_size, struct tm* date, char* rpath, size_t rpath_size) {
+ // check size of result path
+ if (dir_size + 1 > rpath_size) {
+ fprintf(stderr, "Directory path too long");
+ rpath == NULL;
+ return;
+ }
+
+ // add path of the diary dir to result path
+ strcpy(rpath, dir);
- // add path of the diary dir
- strcpy(path, dir);
- if (dir[strlen(dir) - 1] != '/')
- strcat(path, "/");
+ // check for terminating '/' in path
+ if (dir[dir_size - 1] != '/') {
+ // check size again to accomodate '/'
+ if (dir_size + 1 > rpath_size) {
+ fprintf(stderr, "Directory path too long");
+ rpath == NULL;
+ return;
+ }
+ strcat(rpath, "/");
+ }
- // append date to the path
- get_date_str(date, dstr, sizeof(dstr));
- strcat(path, dstr);
+ char dstr[16];
+ get_date_str(date, dstr, sizeof dstr);
- return path;
+ // append date to the result path
+ if (strlen(rpath) + sizeof dstr > rpath_size) {
+ fprintf(stderr, "File path too long");
+ rpath == NULL;
+ return;
+ }
+ strcat(rpath, dstr);
}
-char* edit_cmd(char* dir, struct tm* date) {
- static char ecmd[150];
+void edit_cmd(char* dir, size_t dir_size, struct tm* date, char* rcmd, size_t rcmd_size) {
+ // get editor from environment
char* editor = getenv("EDITOR");
- if (editor == NULL)
- return NULL;
+ if (editor == NULL) {
+ fprintf(stderr, "'EDITOR' environment variable not set");
+ return;
+ }
+
+ // set the edit command to env editor
+ if (strlen(editor) + 2 > rcmd_size) {
+ fprintf(stderr, "Binary path of default editor too long");
+ return;
+ }
+ strcpy(rcmd, editor);
+ strcat(rcmd, " ");
- strcpy(ecmd, editor);
- strcat(ecmd, " ");
- strcat(ecmd, fpath(dir, date));
+ // get path of entry
+ char path[100];
+ fpath(dir, dir_size, date, path, sizeof path);
- return ecmd;
+ // concatenate editor command with entry path
+ if (strlen(rcmd) + strlen(path) + 1 > rcmd_size) {
+ fprintf(stderr, "Edit command too long");
+ return;
+ }
+ strcat(rcmd, path);
}
bool is_leap(int year) {
@@ -106,11 +148,14 @@ bool is_leap(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
-WINDOW* read_diary(char* dir, struct tm* date, WINDOW* prev, int width) {
+WINDOW* read_diary(char* dir, size_t dir_size, struct tm* date, WINDOW* prev, int width) {
wclear(prev);
char buff[width];
+ char path[100];
int i = 0;
- char* path = fpath(dir, date);
+
+ // get entry path
+ fpath(dir, dir_size, date, path, sizeof path);
FILE* fp = fopen(path, "r");
if (fp != NULL) {
@@ -138,13 +183,13 @@ bool go_to(WINDOW* calendar, WINDOW* month_sidebar, time_t date, int* cur_pad_po
getyx(calendar, cy, cx);
- // Remove the STANDOUT attribute from the day we are leaving
+ // remove the STANDOUT attribute from the day we are leaving
chtype current_attrs = mvwinch(calendar, cy, cx) & A_ATTRIBUTES;
- // Leave every attr as is, but turn off STANDOUT
+ // leave every attr as is, but turn off STANDOUT
current_attrs &= ~A_STANDOUT;
mvwchgat(calendar, cy, cx, 2, current_attrs, 0, NULL);
- // Add the STANDOUT attribute to the day we are entering
+ // add the STANDOUT attribute to the day we are entering
chtype new_attrs = mvwinch(calendar, diff_weeks, diff_wdays * 3) & A_ATTRIBUTES;
new_attrs |= A_STANDOUT;
mvwchgat(calendar, diff_weeks, diff_wdays * 3, 2, new_attrs, 0, NULL);
@@ -153,8 +198,8 @@ bool go_to(WINDOW* calendar, WINDOW* month_sidebar, time_t date, int* cur_pad_po
*cur_pad_pos = diff_weeks;
if (diff_weeks > *cur_pad_pos + LINES - 2)
*cur_pad_pos = diff_weeks - LINES + 2;
- prefresh(month_sidebar, *cur_pad_pos, 0, 1, 0, LINES - 1, ASIDE_WIDTH);
- prefresh(calendar, *cur_pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
+ prefresh(month_sidebar, *cur_pad_pos, 0, 1, 0, LINES - 1, ASIDE_WIDTH);
+ prefresh(calendar, *cur_pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
return true;
}
@@ -186,24 +231,38 @@ void setup_cal_timeframe() {
}
int main(int argc, char** argv) {
- // Get the diary directory via environment variable or argument
- // If both are given, the argument takes precedence
- char* diary_dir = NULL;
+ char diary_dir[80];
+ char* env_var;
+
+ // get the diary directory via environment variable or argument
+ // if both are given, the argument takes precedence
if (argc < 2) {
- diary_dir = getenv("DIARY_DIR");
- if (diary_dir == NULL) {
+ // the diary directory is not specified via command line argument
+ // use the environment variable if available
+ env_var = getenv("DIARY_DIR");
+ if (env_var == NULL) {
fprintf(stderr, "The diary directory must ge given as command line "
"argument or in the DIARY_DIR environment variable\n");
return 1;
}
+
+ if (strlen(env_var) + 1 > sizeof diary_dir) {
+ fprintf(stderr, "Diary directory path too long\n");
+ return 1;
+ }
+ strcpy(diary_dir, env_var);
} else {
- diary_dir = argv[1];
+ if (strlen(argv[1]) + 1 > sizeof diary_dir) {
+ fprintf(stderr, "Diary directory path too long\n");
+ return 1;
+ }
+ strcpy(diary_dir, argv[1]);
}
- // Check if that directory exists
+ // check if that directory exists
DIR* diary_dir_ptr = opendir(diary_dir);
if (diary_dir_ptr) {
- // Directory exists, continue
+ // directory exists, continue
closedir(diary_dir_ptr);
} else if (errno == ENOENT) {
fprintf(stderr, "The directory '%s' does not exist\n", diary_dir);
@@ -228,7 +287,7 @@ int main(int argc, char** argv) {
WINDOW* aside = newpad((YEAR_RANGE * 2 + 1) * 12 * MAX_MONTH_HEIGHT, ASIDE_WIDTH);
WINDOW* cal = newpad((YEAR_RANGE * 2 + 1) * 12 * MAX_MONTH_HEIGHT, CAL_WIDTH);
keypad(cal, TRUE);
- draw_calendar(cal, aside, diary_dir);
+ draw_calendar(cal, aside, diary_dir, sizeof diary_dir);
int ch, pad_pos = 0;
struct tm new_date;
@@ -236,21 +295,22 @@ int main(int argc, char** argv) {
int prev_height = LINES - 1;
bool ret = go_to(cal, aside, raw_time, &pad_pos);
- // Mark current day
+ // mark current day
chtype atrs = winch(cal) & A_ATTRIBUTES;
wchgat(cal, 2, atrs | A_UNDERLINE, 0, NULL);
prefresh(cal, pad_pos, 0, 1, ASIDE_WIDTH, LINES - 1, ASIDE_WIDTH + CAL_WIDTH);
WINDOW* prev = newwin(prev_height, prev_width, 1, ASIDE_WIDTH + CAL_WIDTH);
- prev = read_diary(diary_dir, &today, prev, prev_width);
+ prev = read_diary(diary_dir, sizeof diary_dir, &today, prev, prev_width);
do {
ch = wgetch(cal);
new_date = curs_date;
- char* ecmd = edit_cmd(diary_dir, &new_date);
+ char ecmd[150];
+ edit_cmd(diary_dir, sizeof diary_dir, &new_date, ecmd, sizeof ecmd);
switch(ch) {
- // Basic movements
+ // basic movements
case 'j':
case KEY_DOWN:
new_date.tm_mday += 7;
@@ -272,7 +332,7 @@ int main(int argc, char** argv) {
ret = go_to(cal, aside, mktime(&new_date), &pad_pos);
break;
- // Jump to top/bottom of page
+ // jump to top/bottom of page
case 'g':
ret = go_to(cal, aside, mktime(&cal_start), &pad_pos);
break;
@@ -280,7 +340,7 @@ int main(int argc, char** argv) {
ret = go_to(cal, aside, mktime(&cal_end), &pad_pos);
break;
- // Jump backward/forward by a month
+ // jump backward/forward by a month
case 'K':
if (new_date.tm_mday == 1)
new_date.tm_mon--;
@@ -293,12 +353,12 @@ int main(int argc, char** argv) {
ret = go_to(cal, aside, mktime(&new_date), &pad_pos);
break;
- // Today shortcut
+ // today shortcut
case 't':
new_date = today;
ret = go_to(cal, aside, raw_time, &pad_pos);
break;
- // Edit/create a diary entry
+ // edit/create a diary entry
case 'e':
case '\n':
if (ecmd) {
@@ -317,7 +377,7 @@ int main(int argc, char** argv) {
prev_width = COLS - ASIDE_WIDTH - CAL_WIDTH;
wresize(prev, prev_height, prev_width);
- prev = read_diary(diary_dir, &curs_date, prev, prev_width);
+ prev = read_diary(diary_dir, sizeof diary_dir, &curs_date, prev, prev_width);
}
} while (ch != 'q');