1 #define MODULE_LOG_PREFIX "files"
5 #include "oscam-files.h"
6 #include "oscam-lock.h"
7 #include "oscam-string.h"
9 extern CS_MUTEX_LOCK readdir_lock
;
10 extern char cs_tmpdir
[200];
12 /* Gets the tmp dir */
13 char *get_tmp_dir(void)
19 #if defined(__CYGWIN__)
21 char *d
= getenv("TMPDIR");
35 getcwd(cs_tmpdir
, sizeof(cs_tmpdir
) - 1);
38 cs_strncpy(cs_tmpdir
, d
, sizeof(cs_tmpdir
));
42 if(*p
!= '/' && *p
!= '\\')
44 cs_strncat(cs_tmpdir
, "/", sizeof(cs_tmpdir
));
46 cs_strncat(cs_tmpdir
, "_oscam", sizeof(cs_tmpdir
));
48 cs_strncpy(cs_tmpdir
, "/tmp/.oscam", sizeof(cs_tmpdir
));
50 mkdir(cs_tmpdir
, S_IRWXU
);
54 char *get_tmp_dir_filename(char *dest
, size_t destlen
, const char *filename
)
56 char *tmp_dir
= get_tmp_dir();
57 const char *slash
= "/";
58 if(tmp_dir
[cs_strlen(tmp_dir
) - 1] == '/')
62 snprintf(dest
, destlen
, "%s%s%s", tmp_dir
, slash
, filename
);
66 /* Drop-in replacement for readdir_r as some plattforms strip the function from their libc.
67 Furthermore, there are some security issues, see http://womble.decadent.org.uk/readdir_r-advisory.html */
69 int32_t cs_readdir_r(DIR *dirp
, struct dirent
*entry
, struct dirent
**result
)
71 /* According to POSIX the buffer readdir uses is not shared between directory streams.
72 However readdir is not guaranteed to be thread-safe and some implementations may use global state.
73 Thus we use a lock as we have many plattforms... */
76 cs_writelock(__func__
, &readdir_lock
);
78 *result
= readdir(dirp
);
80 if(errno
== 0 && *result
!= NULL
)
82 memcpy(entry
, *result
, sizeof(struct dirent
));
85 cs_writeunlock(__func__
, &readdir_lock
);
89 /* Return 1 if the file exists, else 0 */
90 bool file_exists(const char *filename
)
92 return access(filename
, R_OK
) == 0;
95 /* Copies a file from srcfile to destfile. If an error occured before writing,
96 -1 is returned, else -2. On success, 0 is returned.*/
98 int32_t file_copy(char *srcfile
, char *destfile
)
103 src
= fopen(srcfile
, "r");
106 cs_log("Error opening file %s for reading (errno=%d %s)!", srcfile
, errno
, strerror(errno
));
110 dest
= fopen(destfile
, "w");
113 cs_log("Error opening file %s for writing (errno=%d %s)!", destfile
, errno
, strerror(errno
));
130 cs_log("Error while writing to file %s (errno=%d %s)!", destfile
, errno
, strerror(errno
));
142 /* Overwrites destfile with temp_file. If forceBakOverWrite = 0,
143 the bakfile will not be overwritten if it exists, else it will be.*/
145 int32_t safe_overwrite_with_bak(char *destfile
, char *temp_file
, char *bakfile
, int32_t forceBakOverWrite
)
148 if(file_exists(destfile
))
150 if(forceBakOverWrite
!= 0 || !file_exists(bakfile
))
152 if(file_copy(destfile
, bakfile
) < 0)
154 cs_log("Error copying original config file %s to %s. The original config will be left untouched!", destfile
, bakfile
);
155 if(unlink(temp_file
) < 0)
157 cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
));
164 rc
= file_copy(temp_file
, destfile
);
167 cs_log("An error occured while writing the new config file %s.", destfile
);
170 cs_log("The config will be missing or only partly filled upon next startup as this is a non-recoverable error! Please restore from backup or try again.");
172 if(unlink(temp_file
) < 0)
174 cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
));
179 if(unlink(temp_file
) < 0)
181 cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
));
187 char *get_gbox_filename(char *dest
, size_t destlen
, const char *filename
)
189 char *tmp_dir
= get_tmp_dir();
190 const char *slash
= "/";
192 if(cfg
.gbox_tmp_dir
!= NULL
)
194 if(cfg
.gbox_tmp_dir
[cs_strlen(cfg
.gbox_tmp_dir
) - 1] == '/')
198 snprintf(dest
, destlen
, "%s%s%s", cfg
.gbox_tmp_dir
, slash
, filename
);
202 if(tmp_dir
[cs_strlen(tmp_dir
) - 1] == '/') { slash
= ""; }
203 snprintf(dest
, destlen
, "%s%s%s", tmp_dir
, slash
, filename
);