[tin-dev] [PATCH] create_path() better error messages

Urs Janßen urs at tin.org
Wed Aug 23 08:05:40 CEST 2023


In <mailman.1794.1692719943.1791.tin-dev at tin.org> on Tue, 22 Aug 2023 17:59:01,
    Urs Janßen wrote:
> === modified file 'src/save.c'
> --- old/src/save.c      2023-08-13 06:19:57 +0000
> +++ new/src/save.c      2023-08-22 15:52:03 +0000
> @@ -399,12 +399,10 @@
>  {
>         FILE *fp;
>         char keyappend[MAXKEYLEN], keyoverwrite[MAXKEYLEN], keyquit[MAXKEYLEN];
> -       char mode[3];
> +       char mode[3] = { 'a', '+', '\0'};
/* ... */
> -               error_message(2, _(txt_cannot_open_for_saving), path);
> +               perror_message(_(txt_cannot_open_for_saving), path);
>                 return NULL;
>         }
>  
> @@ -579,41 +575,38 @@

use this chunk instead to also avoid the TOCTOU

=== modified file 'src/save.c'
--- old/src/save.c	2023-08-13 06:19:57 +0000
+++ new/src/save.c	2023-08-23 04:41:43 +0000
@@ -399,57 +399,53 @@
 {
 	FILE *fp;
 	char keyappend[MAXKEYLEN], keyoverwrite[MAXKEYLEN], keyquit[MAXKEYLEN];
-	char mode[3];
 	struct stat st;
 	t_function func;
 
-	strcpy(mode, "a+");
+	if ((fp = fopen(path, "a+")) == NULL) {
+		perror_message(_(txt_cannot_open_for_saving), path);
+		return NULL;
+	}
 
-	/*
-	 * Mailboxes will always be appended to
-	 */
-	if (!mbox && stat(path, &st) != -1) {
+	if (fstat(fileno(fp), &st) != -1) {
 		/*
 		 * Admittedly a special case hack, but it saves failing later on
 		 */
 		if (S_ISDIR(st.st_mode)) {
 			wait_message(2, _(txt_cannot_write_to_directory), path);
+			fclose(fp);
 			return NULL;
 		}
 /* TODO: will this get called every art? Should only be done once/batch */
-/* TODO: or add an option for defaulting on all future queries */
+/* TODO: or add an option for defaulting on all future queries (e.g. A/O) */
 /* TODO: 'truncate' path if query exceeds screen-width */
-		func = prompt_slk_response((tinrc.default_save_mode == 'a' ? SAVE_APPEND_FILE : SAVE_OVERWRITE_FILE),
-				save_append_overwrite_keys,
-				_(txt_append_overwrite_quit), path,
-				PrintFuncKey(keyappend, SAVE_APPEND_FILE, save_append_overwrite_keys),
-				PrintFuncKey(keyoverwrite, SAVE_OVERWRITE_FILE, save_append_overwrite_keys),
-				PrintFuncKey(keyquit, GLOBAL_QUIT, save_append_overwrite_keys));
-
-		switch (func) {
-			case SAVE_OVERWRITE_FILE:
-				strcpy(mode, "w");
-				break;
-
-			case GLOBAL_ABORT:
-			case GLOBAL_QUIT:
-				wait_message(1, _(txt_art_not_saved));
-				return NULL;
-
-			default:	/* SAVE_APPEND_FILE */
-				break;
+		if (!mbox) { /* Mailboxes will always be appended to */
+			func = prompt_slk_response((tinrc.default_save_mode == 'a' ? SAVE_APPEND_FILE : SAVE_OVERWRITE_FILE),
+					save_append_overwrite_keys,
+					_(txt_append_overwrite_quit), path,
+					PrintFuncKey(keyappend, SAVE_APPEND_FILE, save_append_overwrite_keys),
+					PrintFuncKey(keyoverwrite, SAVE_OVERWRITE_FILE, save_append_overwrite_keys),
+					PrintFuncKey(keyquit, GLOBAL_QUIT, save_append_overwrite_keys));
+
+			switch (func) {
+				case SAVE_OVERWRITE_FILE:
+					tinrc.default_save_mode = 'o';
+					if (!ftruncate(fileno(fp), 0L))
+						(void) fseek(fp, 0L, SEEK_SET);
+					break;
+
+				case GLOBAL_ABORT:
+				case GLOBAL_QUIT:
+					fclose(fp);
+					wait_message(1, _(txt_art_not_saved));
+					return NULL;
+
+				default:	/* SAVE_APPEND_FILE */
+					tinrc.default_save_mode = 'a';
+					break;
+			}
 		}
-		if (func == SAVE_OVERWRITE_FILE)
-			tinrc.default_save_mode = 'o';
-		else
-			tinrc.default_save_mode = 'a';
-	}
-
-	if ((fp = fopen(path, mode)) == NULL) {
-		error_message(2, _(txt_cannot_open_for_saving), path);
-		return NULL;
-	}
-
+	}
 	return fp;
 }
 



More information about the tin-dev mailing list