38#include "glue_macos.h"
43#if HAS_UNIX && !__MACOSX__
52static char* xdgGetEnv(
const char *name)
54 char *env = SDL_getenv(name);
55 if ((env != NULL) && (env[0] !=
'\0'))
68static char* xdgEnvDup(
const char *name)
71 env = xdgGetEnv( name );
85static char * xdgGetRelativeHome(
const char *envname,
const char *relativefallback )
88 relhome = xdgEnvDup(envname);
89 if ((relhome == NULL) && (errno != ENOMEM)) {
93 home = xdgGetEnv(
"HOME" );
96 homelen = strlen(home);
97 unsigned int fallbacklength;
98 fallbacklength = strlen( relativefallback );
99 relhome = malloc( homelen + fallbacklength + 1 );
102 memcpy( relhome, home, homelen );
103 memcpy( &relhome[ homelen ], relativefallback, fallbacklength + 1 );
104 relhome[ homelen + fallbacklength ] =
'\0';
126 WARN(_(
"Cannot determine config path, using current directory."));
130 char *path = xdgGetRelativeHome(
"XDG_CONFIG_HOME",
"/.config" );
132 WARN(_(
"$XDG_CONFIG_HOME isn't set, using current directory."));
139 char *path = SDL_getenv(
"APPDATA");
141 WARN(_(
"%%APPDATA%% isn't set, using current directory."));
146#error "Feature needs implementation on this Operating System for Naev to work."
169 WARN(_(
"Cannot determine cache path, using current directory."));
173 char *path = xdgGetRelativeHome(
"XDG_CACHE_HOME",
"/.cache" );
175 WARN(_(
"$XDG_CACHE_HOME isn't set, using current directory."));
182 char *path = SDL_getenv(
"APPDATA");
184 WARN(_(
"%%APPDATA%% isn't set, using current directory."));
189#error "Feature needs implementation on this Operating System for Naev to work."
197#define MKDIR mkdir( opath, mode )
198static int mkpath(
const char *path, mode_t mode )
200#define MKDIR !CreateDirectory( opath, NULL )
201static int mkpath(
const char *path )
203#error "Feature needs implementation on this Operating System for Naev to work."
214 strncpy( opath, path,
sizeof(opath)-1 );
215 opath[
sizeof(opath)-1 ] =
'\0';
225 for (; p >= opath; p--) {
240 for (; p[0] !=
'\0'; p++) {
277 if ( mkpath( path, S_IRWXU | S_IRWXG | S_IRWXO ) < 0 ) {
279 if ( mkpath( path ) < 0 ) {
281#error "Feature needs implementation on this Operating System for Naev to work."
283 WARN( _(
"Dir '%s' does not exist and unable to create: %s" ), path, strerror( errno ) );
323 if ( stat( path, &buf ) == 0 )
353 snprintf(backup,
sizeof(backup),
"%s.backup", path);
379 f_in = fopen( file1,
"rb" );
380 f_out = fopen( file2,
"wb" );
381 if ((f_in==NULL) || (f_out==NULL)) {
382 WARN( _(
"Failure to copy '%s' to '%s': %s"), file1, file2, strerror(errno) );
392 lr = fread( buf, 1,
sizeof(buf), f_in );
401 lw = fwrite( buf, 1, lr, f_out );
402 if (ferror(f_out) || (lr != lw))
413 WARN( _(
"Failure to copy '%s' to '%s': %s"), file1, file2, strerror(errno) );
434 struct stat path_stat;
436 if ( path == NULL ) {
441 if ( stat( path, &path_stat ) ) {
442 WARN( _(
"Error occurred while opening '%s': %s" ), path, strerror( errno ) );
447 if ( !S_ISREG( path_stat.st_mode ) ) {
448 WARN( _(
"Error occurred while opening '%s': It is not a regular file" ), path );
454 file = fopen( path,
"rb" );
455 if ( file == NULL ) {
456 WARN( _(
"Error occurred while opening '%s': %s" ), path, strerror( errno ) );
462 if ( fseek( file, 0L, SEEK_END ) == -1 ) {
463 WARN( _(
"Error occurred while seeking '%s': %s" ), path, strerror( errno ) );
469 if ( fseek( file, 0L, SEEK_SET ) == -1 ) {
470 WARN( _(
"Error occurred while seeking '%s': %s" ), path, strerror( errno ) );
477 buf = malloc( len+1 );
479 WARN(_(
"Out of Memory"));
489 pos = fread( &buf[ n ], 1, len - n, file );
491 WARN( _(
"Error occurred while reading '%s': %s" ), path, strerror( errno ) );
520 f = fopen( path,
"a+b" );
522 WARN( _(
"Unable to touch file '%s': %s" ), path, strerror( errno ) );
548 file = fopen( path,
"wb" );
549 if ( file == NULL ) {
550 WARN( _(
"Error occurred while opening '%s': %s" ), path, strerror( errno ) );
557 pos = fwrite( &data[ n ], 1, len - n, file );
559 WARN( _(
"Error occurred while writing '%s': %s" ), path, strerror( errno ) );
567 if ( fclose( file ) == EOF ) {
568 WARN( _(
"Error occurred while closing '%s': %s" ), path, strerror( errno ) );
592int _nfile_concatPaths(
char buf[
static 1],
int maxLength,
const char path[
static 1], ... )
600 bufEnd = buf + maxLength;
601 va_start( ap, path );
605 if ( section == NULL )
606 WARN( _(
"First argument to nfile_concatPaths was NULL. This is probably an error." ) );
611 if ( section == NULL )
614 if ( bufPos > buf ) {
616 if ( bufPos[ -1 ] !=
'/' ) {
621 if ( *section ==
'/' )
626 bufPos = memccpy( bufPos, section,
'\0', bufEnd - bufPos );
627 if ( bufPos == NULL )
631 section = va_arg( ap,
char * );
632 }
while ( bufPos-- < bufEnd );
636 if ( section != NULL )
Provides macros to work with dynamic arrays.
Header file with generic functions and naev-specifics.
int nfile_copyIfExists(const char *file1, const char *file2)
Copy a file, if it exists.
const char * nfile_configPath(void)
Gets Naev's config path (for user preferences such as conf.lua)
static char naev_configPath[PATH_MAX]
int nfile_writeFile(const char *data, size_t len, const char *path)
Tries to write a file.
static char naev_cachePath[PATH_MAX]
char * nfile_readFile(size_t *filesize, const char *path)
Tries to read a file.
int nfile_dirMakeExist(const char *path)
Creates a directory if it doesn't exist.
int nfile_backupIfExists(const char *path)
Backup a file, if it exists.
const char * nfile_cachePath(void)
Gets Naev's cache path (for cached data such as generated textures)
int nfile_fileExists(const char *path)
Checks to see if a file exists.
int nfile_touch(const char *path)
Tries to create the file if it doesn't exist.
int nfile_isSeparator(uint32_t c)
Checks to see if a character is used to separate files in a path.
int nfile_dirExists(const char *path)
Checks to see if a directory exists.