00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef lint
00039 static char copyright[] =
00040 "@(#) Copyright (c) 2002\n\
00041 Netherlands Forensic Institute. All rights reserved.\n";
00042 #endif
00043
00044 #ifdef HAVE_CONFIG_H
00045 #include <config.h>
00046 #endif
00047
00048 #include <assert.h>
00049 #include <stdarg.h>
00050 #include <sys/types.h>
00051 #include <sys/stat.h>
00052 #include <unistd.h>
00053 #include <fcntl.h>
00054 #include <errno.h>
00055 #include <string.h>
00056
00057 #include "rdd.h"
00058 #include "rdd_internals.h"
00059 #include "error.h"
00060 #include "outfile.h"
00061
00062
00063
00064 static int
00065 path_exists(const char *path, struct stat *info)
00066 {
00067 return stat(path, info) != -1 || errno != ENOENT;
00068 }
00069
00070
00071
00072
00073
00074 int
00075 outfile_open(int *fdp, const char *path, int force_overwrite)
00076 {
00077 struct stat statinfo;
00078 int open_flags;
00079 int fd = -1;
00080
00081 open_flags = O_CREAT|O_WRONLY;
00082 if (path_exists(path, &statinfo)) {
00083 if (S_ISDIR(statinfo.st_mode)) {
00084 unix_error("%s is a directory", path);
00085 }
00086 if (! force_overwrite) {
00087 error("refusing to overwrite %s; use -f", path);
00088 }
00089 if (S_ISREG(statinfo.st_mode)) {
00090 open_flags |= O_TRUNC;
00091 }
00092 }
00093
00094 if ((fd = open(path, open_flags, S_IRUSR|S_IWUSR)) < 0) {
00095 unix_error("cannot open output file %s", path);
00096 }
00097
00098 *fdp = fd;
00099 return RDD_OK;
00100 }
00101
00102 int
00103 outfile_fopen(FILE **fpp, const char *path, int force_overwrite)
00104 {
00105 FILE *fp;
00106 int fd = -1;
00107 int rc = RDD_OK;
00108
00109 if ((rc = outfile_open(&fd, path, force_overwrite)) != RDD_OK) {
00110 return rc;
00111 }
00112
00113 if ((fp = fdopen(fd, "wb")) == NULL) {
00114 return RDD_EOPEN;
00115 }
00116
00117 *fpp = fp;
00118 return RDD_OK;
00119 }
00120
00121
00122
00123 void
00124 outfile_close(int fd, char *path)
00125 {
00126 struct stat statinfo;
00127
00128 if (fd < 0) return;
00129
00130 if (fstat(fd, &statinfo) < 0) {
00131 unix_error("cannot fstat current output file");
00132 }
00133 if (close(fd) < 0) {
00134 unix_error("cannot close %s", path);
00135 }
00136 if (S_ISREG(statinfo.st_mode)
00137 && chmod(path, S_IRUSR|S_IRGRP|S_IROTH) < 0) {
00138
00139
00140
00141 errlognl("cannot make %s read-only", path);
00142 }
00143 }
00144
00145 void
00146 outfile_fclose(FILE *fp, char *path)
00147 {
00148 int fd, fd2;
00149
00150 fflush(fp);
00151 if ((fd = fileno(fp)) < 0) {
00152 unix_error("no file descriptor for stream (%s)", path);
00153 }
00154 if ((fd2 = dup(fd)) < 0) {
00155 unix_error("cannot copy file descriptor (%s)", path);
00156 }
00157 if (fclose(fp) < 0) {
00158 unix_error("cannot close stream (%s)", path);
00159 }
00160 outfile_close(fd2, path);
00161 }