/** * \brief Gets the home cache directory. * * Follows the XDG Base Directory Specification: * http://www.freedesktop.org/Standards/basedir-spec * * \return New string or NULL. */ char* lisys_paths_get_cache_home () { #ifdef __WIN32__ return lisys_paths_get_data_home (); #else char* ret; char* tmp; const char* dir; dir = getenv ("XDG_CACHE_HOME"); if (dir != NULL && dir[0] != '\0') return lisys_string_dup (dir); tmp = lisys_paths_get_home (); if (tmp == NULL) return NULL; ret = lisys_path_concat (tmp, ".cache", NULL); lisys_free (tmp); return ret; #endif }
/** * \brief Creates a new paths object. * * \param path Package root directory or NULL for auto-detect. * \param name Module name. * \return Paths or NULL. */ LIPthPaths* lipth_paths_new ( const char* path, const char* name) { char* tmp; LIPthPaths* self; /* Allocate self. */ self = lisys_calloc (1, sizeof (LIPthPaths)); if (self == NULL) return NULL; /* Allocate the file lookup table. */ self->files = lialg_strdic_new (); if (self->files == NULL) { lipth_paths_free (self); return NULL; } /* Set the module name. */ self->module_name = lisys_string_dup (name); if (self->module_name == NULL) { lipth_paths_free (self); return NULL; } /* Set the root directory. */ if (path != NULL) { self->root = lisys_string_dup (path); if (self->root == NULL) { lipth_paths_free (self); return NULL; } } else { self->root = lipth_paths_get_root (); if (self->root == NULL) { lipth_paths_free (self); return NULL; } } /* Get the data directory root. */ /* This is where modules and system scripts are located. If relative paths are enabled, the directory of the executable is searched for a data directory. Failing that, XDG data directories are searched for the game directory. As the last resort, the hardcoded data directory is used. */ #ifdef LI_RELATIVE_PATHS self->global_data = lisys_path_concat (self->root, "data", NULL); if (!private_validate_dir (&self->global_data)) #endif { self->global_data = lisys_paths_get_data_global ("lipsofsuna"); private_validate_dir (&self->global_data); if (self->global_data == NULL) { #ifdef LIDATADIR self->global_data = lisys_string_dup (LIDATADIR); if (!private_validate_dir (&self->global_data)) #endif { lisys_error_set (EINVAL, "cannot find the data directory"); lipth_paths_free (self); return NULL; } } } /* Get the data directory of the current module. */ /* This is where the data files of the module are installed. The directory functions as a fallback for both data and configuration files. */ self->module_data = lisys_path_concat (self->global_data, name, NULL); if (!private_validate_dir (&self->module_data)) { lisys_error_set (EINVAL, "cannot find the module data directory"); lipth_paths_free (self); return NULL; } /* Get the data save directory. */ /* This is where save files are written and where the user can copy any custom data files or mods. It's the first place where data files are looked for. */ tmp = lisys_paths_get_data_home (); if (tmp == NULL) { lipth_paths_free (self); return NULL; } self->module_data_save = lisys_path_concat (tmp, "lipsofsuna", name, NULL); lisys_free (tmp); if (self->module_data_save == NULL) { lipth_paths_free (self); return NULL; } /* Get the config directory. */ /* This is where configuration files are stored. It's separate from the save directory since in Linux that's the case. In Windows it's actually the save directory. */ tmp = lisys_paths_get_config_home (); if (tmp == NULL) { lipth_paths_free (self); return NULL; } self->module_config = lisys_path_concat (tmp, "lipsofsuna", name, NULL); lisys_free (tmp); if (self->module_config == NULL) { lipth_paths_free (self); return NULL; } /* Get the extension directory. */ /* This directory is reserved for potential third party extension libraries. The path is lib/extensions either in the relative path, XDG data path or the hardcoded extension directory. */ #ifdef LI_RELATIVE_PATHS self->global_exts = lisys_path_concat (self->global_data, "lib", "extensions", NULL); if (!private_validate_dir (&self->global_exts)) #endif { self->global_exts = lisys_paths_get_data_global ("lipsofsuna/lib/extensions"); #ifdef LIEXTSDIR if (!private_validate_dir (&self->global_exts)) { self->global_exts = lisys_string_dup (LIEXTSDIR); private_validate_dir (&self->global_exts); } #endif } /* Create the save directories. */ if (!private_create_save_path (self, self->module_data_save) || !private_create_save_path (self, self->module_config)) { lipth_paths_free (self); return NULL; } /* Add the base data directory. */ lipth_paths_add_path (self, ""); return self; }
/** * \brief Creates a new paths object. * * \param path Package root directory or NULL for auto-detect. * \param name Module name. * \return Paths or NULL. */ LIPthPaths* lipth_paths_new ( const char* path, const char* name) { char* tmp; LIPthPaths* self; LISysStat stat; self = lisys_calloc (1, sizeof (LIPthPaths)); if (self == NULL) return NULL; /* Set module name. */ self->module_name = lisys_string_dup (name); if (self->module_name == NULL) goto error; /* Set root directory. */ if (path != NULL) { self->root = lisys_string_dup (path); if (self->root == NULL) goto error; } else { self->root = lipth_paths_get_root (); if (self->root == NULL) goto error; } /* Get data directory. */ #ifdef LI_RELATIVE_PATHS self->global_data = lisys_path_concat (self->root, "data", NULL); if (self->global_data == NULL) goto error; #else self->global_data = LIDATADIR; #endif self->module_data = lisys_path_concat (self->global_data, name, NULL); if (self->module_data == NULL) goto error; /* Get data override directory. */ tmp = lisys_paths_get_data_home (); if (tmp == NULL) goto error; self->override_data = lisys_path_concat (tmp, "lipsofsuna", "data", name, NULL); if (self->override_data == NULL) { lisys_free (tmp); goto error; } /* Get save directory. */ self->global_state = lisys_path_concat (tmp, "lipsofsuna", "save", NULL); lisys_free (tmp); if (self->global_state == NULL) goto error; self->module_state = lisys_path_concat (self->global_state, name, NULL); if (self->module_state == NULL) goto error; /* Get extension directory. */ #ifdef LI_RELATIVE_PATHS self->global_exts = lisys_path_concat (self->global_data, "lib", "extensions", NULL); if (self->global_exts == NULL) goto error; #else self->global_exts = LIEXTSDIR; #endif /* Check for valid data directory. */ if (!lisys_filesystem_stat (self->module_data, &stat)) { lisys_error_set (EIO, "missing data directory `%s'", self->module_data); goto error; } if (stat.type != LISYS_STAT_DIRECTORY && stat.type != LISYS_STAT_LINK) { lisys_error_set (EIO, "invalid data directory `%s': not a directory", self->module_data); goto error; } return self; error: lipth_paths_free (self); return NULL; }