oscam-2.26.01-11942-802-wit.../oscam-files.c

221 lines
5.0 KiB
C

#define MODULE_LOG_PREFIX "files"
#include "globals.h"
#include "oscam-files.h"
#include "oscam-lock.h"
#include "oscam-string.h"
extern CS_MUTEX_LOCK readdir_lock;
extern char cs_tmpdir[200];
/* Gets the tmp dir */
char *get_tmp_dir(void)
{
if(cs_tmpdir[0])
{
return cs_tmpdir;
}
#if defined(__CYGWIN__)
char *d = getenv("TMPDIR");
if(!d || !d[0])
{
d = getenv("TMP");
}
if(!d || !d[0])
{
d = getenv("TEMP");
}
if(!d || !d[0])
{
getcwd(cs_tmpdir, sizeof(cs_tmpdir) - 1);
}
cs_strncpy(cs_tmpdir, d, sizeof(cs_tmpdir));
char *p = cs_tmpdir;
while(*p) { p++; }
p--;
if(*p != '/' && *p != '\\')
{
cs_strncat(cs_tmpdir, "/", sizeof(cs_tmpdir));
}
cs_strncat(cs_tmpdir, "_oscam", sizeof(cs_tmpdir));
#else
cs_strncpy(cs_tmpdir, "/tmp/.oscam", sizeof(cs_tmpdir));
#endif
mkdir(cs_tmpdir, S_IRWXU);
return cs_tmpdir;
}
char *get_tmp_dir_filename(char *dest, size_t destlen, const char *filename)
{
char *tmp_dir = get_tmp_dir();
const char *slash = "/";
if(tmp_dir[cs_strlen(tmp_dir) - 1] == '/')
{
slash = "";
}
snprintf(dest, destlen, "%s%s%s", tmp_dir, slash, filename);
return dest;
}
/* Return 1 if the file exists, else 0 */
bool file_exists(const char *filename)
{
return access(filename, R_OK) == 0;
}
/* Finds a file in the system PATH.
Returns a newly allocated string with the full path, or NULL if not found.
Caller must free() the returned string. */
char *find_in_path(const char *filename)
{
// If filename already has '/', don't search PATH
if (strchr(filename, '/')) {
return strdup(filename);
}
char *paths; const char *path = getenv("PATH"); if (!path || !(paths = strdup(path))) return NULL;
char *saveptr = NULL;
char *dir = strtok_r(paths, ":", &saveptr);
char fullpath[PATH_MAX];
char *result = NULL;
while (dir) {
if (*dir == '\0') dir = ".";
snprintf(fullpath, sizeof(fullpath), "%s/%s", dir, filename);
if (file_exists(fullpath)) {
result = strdup(fullpath);
break;
}
dir = strtok_r(NULL, ":", &saveptr);
}
free(paths);
return result;
}
/* Copies a file from srcfile to destfile. If an error occured before writing,
-1 is returned, else -2. On success, 0 is returned.*/
int32_t file_copy(char *srcfile, char *destfile)
{
FILE *src, *dest;
int32_t ch;
src = fopen(srcfile, "r");
if(!src)
{
cs_log("Error opening file %s for reading (errno=%d %s)!", srcfile, errno, strerror(errno));
return -1;
}
dest = fopen(destfile, "w");
if(!dest)
{
cs_log("Error opening file %s for writing (errno=%d %s)!", destfile, errno, strerror(errno));
fclose(src);
return -1;
}
while(1)
{
ch = fgetc(src);
if(ch == EOF)
{
break;
}
else
{
fputc(ch, dest);
if(ferror(dest))
{
cs_log("Error while writing to file %s (errno=%d %s)!", destfile, errno, strerror(errno));
fclose(src);
fclose(dest);
return -2;
}
}
}
fclose(src);
if(fsync(fileno(dest)) == -1) // Dodano fsync, aby wymusić zapis na dysk
{
cs_log("ERROR: file_copy - fsync failed for %s (errno=%d %s)!", destfile, errno, strerror(errno));
}
fclose(dest);
return (0);
}
/* Overwrites destfile with temp_file. If forceBakOverWrite = 0,
the bakfile will not be overwritten if it exists, else it will be.*/
int32_t safe_overwrite_with_bak(char *destfile, char *temp_file, char *bakfile, int32_t forceBakOverWrite)
{
int32_t rc;
if(file_exists(destfile))
{
if(forceBakOverWrite != 0 || !file_exists(bakfile))
{
if(file_copy(destfile, bakfile) < 0)
{
cs_log("ERROR: safe_overwrite_with_bak - Error copying original config file %s to %s. The original config will be left untouched!", destfile, bakfile);
if(unlink(temp_file) < 0)
{
cs_log("ERROR: safe_overwrite_with_bak - Error removing temp config file %s (errno=%d %s)!", temp_file, errno, strerror(errno));
}
return 1;
}
}
}
rc = file_copy(temp_file, destfile);
if(rc < 0)
{
cs_log("ERROR: safe_overwrite_with_bak - An error occured while writing the new config file %s. Return code: %d, errno: %d (%s).", destfile, rc, errno, strerror(errno));
if(rc == -2)
{
cs_log("ERROR: safe_overwrite_with_bak - 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.");
}
if(unlink(temp_file) < 0)
{
cs_log("ERROR: safe_overwrite_with_bak - Error removing temp config file %s (errno=%d %s)!", temp_file, errno, strerror(errno));
}
return 1;
}
if(unlink(temp_file) < 0)
{
cs_log("ERROR: safe_overwrite_with_bak - Error removing temp config file %s (errno=%d %s)!", temp_file, errno, strerror(errno));
}
return 0;
}
#ifdef MODULE_GBOX
char *get_gbox_filename(char *dest, size_t destlen, const char *filename)
{
char *tmp_dir = get_tmp_dir();
const char *slash = "/";
if(cfg.gbox_tmp_dir != NULL)
{
if(cfg.gbox_tmp_dir[cs_strlen(cfg.gbox_tmp_dir) - 1] == '/')
{
slash = "";
}
snprintf(dest, destlen, "%s%s%s", cfg.gbox_tmp_dir, slash, filename);
}
else
{
if(tmp_dir[cs_strlen(tmp_dir) - 1] == '/') { slash = ""; }
snprintf(dest, destlen, "%s%s%s", tmp_dir, slash, filename);
}
return dest;
}
#endif