diff options
-rw-r--r-- | worker/output_handler.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/worker/output_handler.c b/worker/output_handler.c index 2e8819a..5a1b48e 100644 --- a/worker/output_handler.c +++ b/worker/output_handler.c @@ -56,11 +56,28 @@ static int copy_file(const char *src_name, const char *dest_name) { void *dest; char *tmp_file_name=NULL; - tmp_file_name=(char *) malloc(strlen(src_name)+7); + tmp_file_name=(char *) malloc(strlen(dest_name)+8); CHECK(tmp_file_name, NULL, ("malloc failed."), return -1); - strcpy(tmp_file_name, src_name); + strcpy(tmp_file_name, dest_name); strcat(tmp_file_name, ".XXXXXX"); + if ( (ret=lstat(src_name, &stat_buffer)) == -1) { + if (errno != ENOENT) { + DEBUG(0,("stat on %s failed: %s\n",src_name, strerror(errno))); + goto cleanup; + } + DEBUG(0,("stat on %s failed with ENOENT, I will create an empty copy.\n",src_name, strerror(errno))); + + dest_fd=open_temporary_file(tmp_file_name, "0600", "root", "root", NULL); + CHECK(dest_fd, -1, ("Failed to open temporary file %s\n", tmp_file_name), goto cleanup); + + close(dest_fd); + ret=rename(tmp_file_name, dest_name); + CHECK(ret, -1, ("Cannot rename %s to %s: %s\n", tmp_file_name, dest_name, strerror(errno) ), goto cleanup); + + goto cleanup; + } + ret=-1; src_fd = open(src_name, O_RDONLY); CHECK(src_fd, -1, ("Failed to open %s read-only.\n", src_name), goto cleanup); @@ -111,6 +128,7 @@ cleanup: return ret; } + static int check_dir_create(const char *name) { int ret; struct stat stat_buffer; @@ -137,13 +155,17 @@ static int safe_config_file(const char *name, const char *app_name) { char *base_name=NULL; if ( (ret=lstat(name, &stat_buffer)) == -1) { - DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); - goto cleanup; - } - if (!S_ISREG(stat_buffer.st_mode)) { - DEBUG(0,("%s is not a regular file!\n",name)); - ret=-1; - goto cleanup; + if (errno != ENOENT) { + DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); + goto cleanup; + } + DEBUG(0,("stat on %s failed with ENOENT, I will create an empty backup file.\n",name, strerror(errno))); + } else { + if (!S_ISREG(stat_buffer.st_mode)) { + DEBUG(0,("%s is not a regular file!\n",name)); + ret=-1; + goto cleanup; + } } ret=check_dir_create(BACKUP_PATH); @@ -245,13 +267,17 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil } if( (ret=lstat(name, &stat_buffer)) == -1) { - DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); - goto cleanup; - } - if(!S_ISREG(stat_buffer.st_mode)) { - DEBUG(0,("%s is not a regular file!\n",name)); - ret=-1; - goto cleanup; + if ( errno != ENOENT ) { + DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); + goto cleanup; + } + DEBUG(0,("stat on %s failed with ENOENT, this is ok\n",name, strerror(errno))); + } else { + if(!S_ISREG(stat_buffer.st_mode)) { + DEBUG(0,("%s is not a regular file!\n",name)); + ret=-1; + goto cleanup; + } } owner=get_output_handler_parameter(node, "owner", "root", 0); @@ -268,7 +294,7 @@ int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_fil ret=safe_config_file(name, app_name); CHECK(ret, -1, ("Failed to safe config file %s of application %s.\n", name, app_name), goto cleanup); - tmp_file_name=(char *) malloc(strlen(name)+7); + tmp_file_name=(char *) malloc(strlen(name)+8); CHECK_NULL_RETURN(tmp_file_name,("malloc failed.")); strcpy(tmp_file_name, name); strcat(tmp_file_name, ".XXXXXX"); |