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)
17 #if defined(__CYGWIN__)
18 char *d
= getenv("TMPDIR");
20 { d
= getenv("TMP"); }
22 { d
= getenv("TEMP"); }
24 { getcwd(cs_tmpdir
, sizeof(cs_tmpdir
) - 1); }
26 cs_strncpy(cs_tmpdir
, d
, sizeof(cs_tmpdir
));
30 if(*p
!= '/' && *p
!= '\\')
31 { strcat(cs_tmpdir
, "/"); }
32 strcat(cs_tmpdir
, "_oscam");
34 cs_strncpy(cs_tmpdir
, "/tmp/.oscam", sizeof(cs_tmpdir
));
36 mkdir(cs_tmpdir
, S_IRWXU
);
40 char *get_tmp_dir_filename(char *dest
, size_t destlen
, const char *filename
)
42 char *tmp_dir
= get_tmp_dir();
43 const char *slash
= "/";
44 if(tmp_dir
[strlen(tmp_dir
) - 1] == '/') { slash
= ""; }
45 snprintf(dest
, destlen
, "%s%s%s", tmp_dir
, slash
, filename
);
49 /* Drop-in replacement for readdir_r as some plattforms strip the function from their libc.
50 Furthermore, there are some security issues, see http://womble.decadent.org.uk/readdir_r-advisory.html */
51 int32_t cs_readdir_r(DIR *dirp
, struct dirent
*entry
, struct dirent
**result
)
53 /* According to POSIX the buffer readdir uses is not shared between directory streams.
54 However readdir is not guaranteed to be thread-safe and some implementations may use global state.
55 Thus we use a lock as we have many plattforms... */
57 cs_writelock(__func__
, &readdir_lock
);
59 *result
= readdir(dirp
);
61 if(errno
== 0 && *result
!= NULL
)
63 memcpy(entry
, *result
, sizeof(struct dirent
));
66 cs_writeunlock(__func__
, &readdir_lock
);
70 /* Return 1 if the file exists, else 0 */
71 bool file_exists(const char *filename
)
73 return access(filename
, R_OK
) == 0;
76 /* Copies a file from srcfile to destfile. If an error occured before writing, -1 is returned, else -2. On success, 0 is returned.*/
77 int32_t file_copy(char *srcfile
, char *destfile
)
81 src
= fopen(srcfile
, "r");
84 cs_log("Error opening file %s for reading (errno=%d %s)!", srcfile
, errno
, strerror(errno
));
87 dest
= fopen(destfile
, "w");
90 cs_log("Error opening file %s for writing (errno=%d %s)!", destfile
, errno
, strerror(errno
));
106 cs_log("Error while writing to file %s (errno=%d %s)!", destfile
, errno
, strerror(errno
));
118 /* Overwrites destfile with temp_file. If forceBakOverWrite = 0, the bakfile will not be overwritten if it exists, else it will be.*/
119 int32_t safe_overwrite_with_bak(char *destfile
, char *temp_file
, char *bakfile
, int32_t forceBakOverWrite
)
122 if(file_exists(destfile
))
124 if(forceBakOverWrite
!= 0 || !file_exists(bakfile
))
126 if(file_copy(destfile
, bakfile
) < 0)
128 cs_log("Error copying original config file %s to %s. The original config will be left untouched!", destfile
, bakfile
);
129 if(unlink(temp_file
) < 0)
130 { cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
)); }
135 rc
= file_copy(temp_file
, destfile
);
138 cs_log("An error occured while writing the new config file %s.", destfile
);
140 { 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."); }
141 if(unlink(temp_file
) < 0)
142 { cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
)); }
145 if(unlink(temp_file
) < 0)
146 { cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file
, errno
, strerror(errno
)); }
151 char *get_gbox_filename(char *dest
, size_t destlen
, const char *filename
)
153 char *tmp_dir
= get_tmp_dir();
154 const char *slash
= "/";
155 if(cfg
.gbox_tmp_dir
!= NULL
)
157 if(cfg
.gbox_tmp_dir
[strlen(cfg
.gbox_tmp_dir
) - 1] == '/') { slash
= ""; }
158 snprintf(dest
, destlen
, "%s%s%s", cfg
.gbox_tmp_dir
, slash
, filename
);
162 if(tmp_dir
[strlen(tmp_dir
) - 1] == '/') { slash
= ""; }
163 snprintf(dest
, destlen
, "%s%s%s", tmp_dir
, slash
, filename
);