From 18d4325f18549897101c1b631508bfa9da9e8f1c Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sun, 19 Jul 2009 16:59:47 +0200
Subject: [PATCH] Improved file manipulation error messages regarding EACCES
 error.

---
 src/lib-sieve/sieve-binary.c | 35 ++++++++++++++++++++++++------
 src/lib-sieve/sieve-error.c  | 42 ++++++++++++++++++++++--------------
 src/lib-sieve/sieve-script.c | 22 ++++++++++++-------
 3 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index de1f00aa4..c25e633ee 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -9,6 +9,7 @@
 #include "hash.h"
 #include "array.h"
 #include "ostream.h"
+#include "eacces-error.h"	
 
 #include "sieve-error.h"
 #include "sieve-extensions.h"
@@ -630,7 +631,13 @@ bool sieve_binary_save
 	temp_path = t_strconcat(path, ".tmp", NULL);
 	fd = open(temp_path, O_CREAT | O_TRUNC | O_WRONLY, save_mode);
 	if ( fd < 0 ) {
-		sieve_sys_error("open(%s) failed for binary save: %m", temp_path);
+		if ( errno == EACCES ) {
+			sieve_sys_error("failed to save binary: %s",
+				eacces_error_get_creating("open", temp_path));
+		} else {
+			sieve_sys_error("failed to save binary: open(%s) failed: %m", 
+				temp_path);
+		}
 		return FALSE;
 	}
 
@@ -639,12 +646,18 @@ bool sieve_binary_save
 	o_stream_destroy(&stream);
  
 	if (close(fd) < 0)
-		sieve_sys_error("close(fd) failed for binary save: %m");
+		sieve_sys_error("failed to close saved binary temporary file: "
+			"close(fd=%s) failed: %m", temp_path);
 
 	/* Replace any original binary atomically */
 	if (result && (rename(temp_path, path) < 0)) {
-		sieve_sys_error("rename(%s, %s) failed for binary save: %m",
-			temp_path, path);
+		if ( errno == EACCES ) {
+			sieve_sys_error("failed to replace existing binary: %s", 
+				eacces_error_get_creating("rename", path));			
+		} else { 		
+			sieve_sys_error("failed to replace existing binary: "
+				"rename(%s, %s) failed: %m", temp_path, path);
+		}
 		result = FALSE;
 	}
 
@@ -672,14 +685,21 @@ static bool sieve_binary_file_open
 	
 	if ( (fd=open(path, O_RDONLY)) < 0 ) {
 		if ( errno != ENOENT ) {
-			sieve_sys_error("binary open(%s) failed: %m", path);
+			if ( errno == EACCES ) {
+				sieve_sys_error("failed to open binary: %s", 
+					eacces_error_get("open", path));			
+			} else {
+				sieve_sys_error("failed to open binary: "
+					"open(%s) failed: %m", path);
+			}
 		}
 		return FALSE;
 	}
 
 	if ( fstat(fd, &st) < 0 ) {
 		if ( errno != ENOENT ) {
-			sieve_sys_error("binary stat(%s) failed: %m", path);
+			sieve_sys_error("failed to open binary: "
+				"fstat(fd=%s) failed: %m", path);
 		}
 		return FALSE;
 	}
@@ -699,7 +719,8 @@ static void sieve_binary_file_close(struct sieve_binary_file **file)
 {
 	if ( (*file)->fd != -1 ) {
 		if ( close((*file)->fd) < 0 ) {
-			sieve_sys_error("binary close(fd) failed: %m");
+			sieve_sys_error("failed to close opened binary: "
+				"close(fd=%s) failed: %m", (*file)->path);
 		}
 	}
 
diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c
index 51bf7e5b7..10771171e 100644
--- a/src/lib-sieve/sieve-error.c
+++ b/src/lib-sieve/sieve-error.c
@@ -4,6 +4,7 @@
 #include "lib.h"
 #include "str.h"
 #include "ostream.h"
+#include "eacces-error.h"
 
 #include "sieve-common.h"
 #include "sieve-script.h"
@@ -536,21 +537,25 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 
 	fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600);
 	if (fd == -1) {
-		sieve_sys_error("failed to open logfile %s (logging to STDERR): %m", 
-			ehandler->logfile);
+		if ( errno == EACCES ) {
+			sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
+				eacces_error_get_creating("open", ehandler->logfile));
+		} else {
+			sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
+				"open(%s) failed: %m", ehandler->logfile);
+		}
 		fd = STDERR_FILENO;
 	} else {
 		/* fd_close_on_exec(fd, TRUE); Necessary? */
 
 		/* Stat the log file to obtain size information */
 		if ( fstat(fd, &st) != 0 ) {
-			sieve_sys_error(
-				"failed to fstat opened logfile %s (logging to STDERR): %m", 
-				ehandler->logfile);
+			sieve_sys_error("failed to stat logfile (logging to STDERR): "
+				"fstat(fd=%s) failed: %m", ehandler->logfile);
 			
 			if ( close(fd) < 0 ) {
-				sieve_sys_error("close(fd) failed for logfile '%s': %m",
-					ehandler->logfile);
+				sieve_sys_error("failed to close logfile after error: "
+					"close(fd=%s) failed: %m", ehandler->logfile);
 			}
 
 			fd = STDERR_FILENO;
@@ -562,23 +567,27 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 			
 			/* Close open file */
 			if ( close(fd) < 0 ) {
-				sieve_sys_error("close(fd) failed for logfile '%s': %m",
+				sieve_sys_error("failed to close logfile: close(fd=%s) failed: %m",
 					ehandler->logfile);
 			}
 			
 			/* Rotate logfile */
 			rotated = t_strconcat(ehandler->logfile, ".0", NULL);
 			if ( rename(ehandler->logfile, rotated) < 0 ) {
-				sieve_sys_error(
-					"failed to rename logfile %s to %s: %m", 
+				sieve_sys_error("failed to rotate logfile: rename(%s, %s) failed: %m", 
 					ehandler->logfile, rotated);
 			}
 			
 			/* Open clean logfile (overwrites existing if rename() failed earlier) */
 			fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600);
 			if (fd == -1) {
-				sieve_sys_error("failed to open logfile %s (logging to STDERR): %m", 
-					ehandler->logfile);
+				if ( errno == EACCES ) {
+					sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
+						eacces_error_get_creating("open", ehandler->logfile));
+				} else {
+					sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
+						"open(%s) failed: %m", ehandler->logfile);
+				}
 				fd = STDERR_FILENO;
 			}
 		}
@@ -587,8 +596,9 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 	ostream = o_stream_create_fd(fd, 0, FALSE);
 	if ( ostream == NULL ) {
 		/* Can't we do anything else in this most awkward situation? */
-		sieve_sys_error("failed to open log stream on open file %s: "
-			"non-critical messages will not be logged!", ehandler->logfile);
+		sieve_sys_error("failed to open log stream on open file: "
+			"o_stream_create_fd(fd=%s) failed "
+			"(non-critical messages are not logged!)", ehandler->logfile);
 	} 
 
 	ehandler->fd = fd;
@@ -652,8 +662,8 @@ static void sieve_logfile_free
 		o_stream_destroy(&(handler->stream));
 		if ( handler->fd != STDERR_FILENO ){
 			if ( close(handler->fd) < 0 ) {
-				sieve_sys_error("close(fd) failed for logfile '%s': %m",
-					handler->logfile);
+				sieve_sys_error("failed to close logfile: "
+					"close(fd=%s) failed: %m", handler->logfile);
 			}
 		}
 	}
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index 75908ba30..141f63aa8 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -4,6 +4,7 @@
 #include "lib.h"
 #include "compat.h"
 #include "istream.h"
+#include "eacces-error.h"
 
 #include "sieve-common.h"
 #include "sieve-error.h"
@@ -108,7 +109,7 @@ struct sieve_script *sieve_script_init
 					*exists_r = FALSE;
 			} else
 				sieve_critical(ehandler, basename, 
-					"failed to lstat sieve script file '%s': %m", path);
+					"failed to stat sieve script: lstat(%s) failed: %m", path);
 
 			script = NULL;
 			ret = 1;
@@ -127,7 +128,7 @@ struct sieve_script *sieve_script_init
 							*exists_r = FALSE;
 					} else
 						sieve_critical(ehandler, basename, 
-							"failed to stat sieve script file '%s': %m", path);
+							"failed to stat sieve script: stat(%s) failed: %m", path);
 
 					script = NULL;	
 					ret = 1;
@@ -266,28 +267,33 @@ struct istream *sieve_script_open
 		*deleted_r = FALSE;
 
 	if ( (fd=open(script->path, O_RDONLY)) < 0 ) {
-		if ( errno == ENOENT ) 
+		if ( errno == ENOENT ) {
 			if ( deleted_r == NULL ) 
 				/* Not supposed to occur, create() does stat already */
 				sieve_error(script->ehandler, script->basename, 
 					"sieve script does not exist");
 			else 
 				*deleted_r = TRUE;
-		else
+		} else if ( errno == EACCES ) {
+			sieve_critical(script->ehandler, script->path,
+				"failed to open sieve script: %s",
+				eacces_error_get("open", script->path));
+		} else {
 			sieve_critical(script->ehandler, script->path, 
-				"failed to open sieve script: %m");
+				"failed to open sieve script: open(%s) failed: %m", script->path);
+		}
 		return NULL;
 	}	
 	
 	if ( fstat(fd, &st) != 0 ) {
 		sieve_critical(script->ehandler, script->path, 
-			"failed to fstat opened sieve script: %m");
+			"failed to open sieve script: fstat(fd=%s) failed: %m", script->path);
 		result = NULL;
 	} else {
 		/* Re-check the file type just to be sure */
 		if ( !S_ISREG(st.st_mode) ) {
 			sieve_critical(script->ehandler, script->path,
-				"opened sieve script file is not a regular file");
+				"sieve script file '%s' is not a regular file", script->path);
 			result = NULL;
 		} else {
 			result = script->stream = 
@@ -300,7 +306,7 @@ struct istream *sieve_script_open
 		/* Something went wrong, close the fd */
 		if ( close(fd) != 0 ) {
 			sieve_sys_error(
-				"close(fd) failed for sieve script %s: %m", 
+				"failed to close sieve script: close(fd=%s) failed: %m", 
 				script->path);
 		}
 	}
-- 
GitLab