- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / oscam-files.c
blobfe073e61d3c69a3ea9c5f99364e214800e73a836
1 #define MODULE_LOG_PREFIX "files"
3 #include "globals.h"
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)
15 if(cs_tmpdir[0])
17 return cs_tmpdir;
19 #if defined(__CYGWIN__)
21 char *d = getenv("TMPDIR");
23 if(!d || !d[0])
25 d = getenv("TMP");
28 if(!d || !d[0])
30 d = getenv("TEMP");
33 if(!d || !d[0])
35 getcwd(cs_tmpdir, sizeof(cs_tmpdir) - 1);
38 cs_strncpy(cs_tmpdir, d, sizeof(cs_tmpdir));
39 char *p = cs_tmpdir;
40 while(*p) { p++; }
41 p--;
42 if(*p != '/' && *p != '\\')
44 cs_strncat(cs_tmpdir, "/", sizeof(cs_tmpdir));
46 cs_strncat(cs_tmpdir, "_oscam", sizeof(cs_tmpdir));
47 #else
48 cs_strncpy(cs_tmpdir, "/tmp/.oscam", sizeof(cs_tmpdir));
49 #endif
50 mkdir(cs_tmpdir, S_IRWXU);
51 return cs_tmpdir;
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] == '/')
60 slash = "";
62 snprintf(dest, destlen, "%s%s%s", tmp_dir, slash, filename);
63 return dest;
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... */
75 int32_t rc;
76 cs_writelock(__func__, &readdir_lock);
77 errno = 0;
78 *result = readdir(dirp);
79 rc = errno;
80 if(errno == 0 && *result != NULL)
82 memcpy(entry, *result, sizeof(struct dirent));
83 *result = entry;
85 cs_writeunlock(__func__, &readdir_lock);
86 return rc;
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)
100 FILE *src, *dest;
101 int32_t ch;
103 src = fopen(srcfile, "r");
104 if(!src)
106 cs_log("Error opening file %s for reading (errno=%d %s)!", srcfile, errno, strerror(errno));
107 return -1;
110 dest = fopen(destfile, "w");
111 if(!dest)
113 cs_log("Error opening file %s for writing (errno=%d %s)!", destfile, errno, strerror(errno));
114 fclose(src);
115 return -1;
118 while(1)
120 ch = fgetc(src);
121 if(ch == EOF)
123 break;
125 else
127 fputc(ch, dest);
128 if(ferror(dest))
130 cs_log("Error while writing to file %s (errno=%d %s)!", destfile, errno, strerror(errno));
131 fclose(src);
132 fclose(dest);
133 return -2;
137 fclose(src);
138 fclose(dest);
139 return (0);
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)
147 int32_t rc;
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));
159 return 1;
164 rc = file_copy(temp_file, destfile);
165 if(rc < 0)
167 cs_log("An error occured while writing the new config file %s.", destfile);
168 if(rc == -2)
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));
176 return 1;
179 if(unlink(temp_file) < 0)
181 cs_log("Error removing temp config file %s (errno=%d %s)!", temp_file, errno, strerror(errno));
183 return 0;
186 #ifdef MODULE_GBOX
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] == '/')
196 slash = "";
198 snprintf(dest, destlen, "%s%s%s", cfg.gbox_tmp_dir, slash, filename);
200 else
202 if(tmp_dir[cs_strlen(tmp_dir) - 1] == '/') { slash = ""; }
203 snprintf(dest, destlen, "%s%s%s", tmp_dir, slash, filename);
205 return dest;
207 #endif