static char * tth_cache_pathname(const struct tth *tth) { const char *hash; g_assert(tth); hash = tth_base32(tth); return h_strdup_printf("%s%c%2.2s%c%s", tth_cache_directory(), G_DIR_SEPARATOR, &hash[0], G_DIR_SEPARATOR, &hash[2]); }
char * bitzi_gui_get_metadata(const bitzi_data_t *data) { g_assert(data != NULL); /* * Build string */ if ( data->judgment == BITZI_FJ_FAILURE || data->judgment == BITZI_FJ_WRONG_FILESIZE ) { return h_strdup(bitzi_fj_to_string(data->judgment)); } else if (data->mime_type) { if (data->mime_desc) { return h_strdup_printf("%s (%1.1f): %s (%s)%s%s", bitzi_fj_to_string(data->judgment), data->goodness, data->mime_type, data->mime_desc, data->duration != 0 ? "; " : "", data->duration != 0 ? short_time(data->duration) : ""); } else { return h_strdup_printf("%s (%1.1f): %s%s%s", bitzi_fj_to_string(data->judgment), data->goodness, data->mime_type, data->duration != 0 ? "; " : "", data->duration != 0 ? short_time(data->duration) : ""); } } else if (data->judgment != BITZI_FJ_UNKNOWN) { return h_strdup_printf("%s (%1.1f): %s", bitzi_fj_to_string(data->judgment), data->goodness, _("No other data")); } return NULL; }
/** * Allocate a prefix as a shorthand for the URI. * * @return prefix string to use, which will be freed by symbol tables * when leaving scope. */ static const char * xfmt_new_prefix(struct xfmt_pass2 *xp2, const char *uri) { const char *prefix = NULL; bool free_prefix = FALSE; /* The URI must not already exist in the symbol table */ g_assert(NULL == symtab_lookup(xp2->uris, uri)); /* * Check whether user has a preference for the prefix to use. * * If there is a prefix, there must be no identical prefix in scope * currently. */ if (xp2->uri2prefix != NULL) prefix = nv_table_lookup_str(xp2->uri2prefix, uri); if (prefix != NULL) { const char *used_uri = symtab_lookup(xp2->prefixes, prefix); if (used_uri != NULL) { g_carp("XFMT cannot use prefix '%s' for '%s': " "already used by '%s'", prefix, uri, used_uri); prefix = NULL; } } /* * Allocate a new prefix if required. */ if (NULL == prefix) { prefix = h_strdup_printf("ns%u", xp2->pcount++); free_prefix = TRUE; } /* * Record associations in the symbol tables. */ xfmt_ns_declare(xp2, prefix, uri, free_prefix); return prefix; }
/** * Close configuration file opened for writing, and rename it. * * @returns TRUE on success. */ bool file_config_close(FILE *out, const file_path_t *fv) { char *path = NULL; char *path_new = NULL; bool success = FALSE; /* * Be extra careful when operating on filesystems with delayed disk block * allocation, such as "ext4". If there is a crash and the data was not * properly allocated to disk, we could lose both the old and new file data! * * To fight against that, make sure we sync the new data to disk before * renaming the new file into the old, as the rename operation is likely * to be stored on disk before allocation of the new data blocks is made. * --RAM, 2013-08-12 */ if (0 != file_sync_fclose(out)) { s_warning("could not flush \"%s\": %m", fv->name); goto failed; } path = make_pathname(fv->dir, fv->name); g_return_val_if_fail(NULL != path, FALSE); path_new = h_strdup_printf("%s.%s", path, new_ext); if (NULL == path_new) goto failed; if (-1 == rename(path_new, path)) { s_warning("could not rename \"%s\" as \"%s\": %m", path_new, path); goto failed; } success = TRUE; failed: HFREE_NULL(path_new); HFREE_NULL(path); return success; }
/** * Open configuration file, renaming it as ".orig" when `renaming' is TRUE. * If configuration file cannot be found, try opening the ".orig" variant * if already present and `renaming' is TRUE. * If not found, try with successive alternatives, if supplied. * * @attention * NB: the supplied `fv' argument is a vector of `fvcnt' elements. Items * with a NULL `dir' field are ignored, but fv[0].dir cannot be NULL. * * @param what is what is being opened, for logging purposes. * @param fv is a vector of files to try to open, in sequence * @param fvcnt is the size of the vector * @param renaming indicates whether the opened file should be renamed .orig. * @param chosen is filled with the index of the chosen path in the vector, * unless NULL is given. * * @return opened FILE, or NULL if we were unable to open any. `chosen' is * only filled if the file is opened. */ static FILE * open_read( const char *what, const file_path_t *fv, int fvcnt, bool renaming, int *chosen) { FILE *in; char *path; char *path_orig; const char *instead = empty_str; int idx = 0; g_assert(fv != NULL); g_assert(fvcnt >= 1); g_assert(fv->dir != NULL); path = make_pathname(fv->dir, fv->name); if (!is_absolute_path(path)) { HFREE_NULL(path); return NULL; } path_orig = h_strdup_printf("%s.%s", path, orig_ext); in = fopen(path, "r"); if (in) { if (is_running_on_mingw()) { /* Windows can't rename an open file */ fclose(in); in = NULL; } if (renaming && -1 == rename(path, path_orig)) { s_warning("[%s] could not rename \"%s\" as \"%s\": %m", what, path, path_orig); } if (NULL == in) { in = fopen(path_orig, "r"); } goto out; } else { if (ENOENT == errno) { if (common_dbg > 0) { g_debug("[%s] cannot load non-existent \"%s\"", what, path); } } else { instead = instead_str; /* Regular file was present */ s_warning("[%s] failed to retrieve from \"%s\": %m", what, path); } if (fvcnt > 1 && common_dbg > 0) g_debug("[%s] trying to load from alternate locations...", what); } /* * Maybe we crashed after having retrieved the file in a previous run * but before being able to write it again correctly? Try to open the * ".orig" file instead. */ g_assert(in == NULL); if (renaming) in = fopen(path_orig, "r"); /* The ".orig", in case of a crash */ if (in != NULL) { instead = instead_str; HFREE_NULL(path); path = path_orig; path_orig = NULL; } /* * Try with alternatives, if supplied. */ if (in == NULL && fvcnt > 1) { const file_path_t *xfv; int xfvcnt; instead = instead_str; for (xfv = fv + 1, xfvcnt = fvcnt - 1; xfvcnt; xfv++, xfvcnt--) { HFREE_NULL(path); if (NULL == xfv->dir) /* In alternatives, dir may be NULL */ continue; path = make_pathname(xfv->dir, xfv->name); idx++; if (NULL != path && NULL != (in = fopen(path, "r"))) break; if (path != NULL && common_dbg > 0) { g_debug("[%s] cannot load non-existent \"%s\" either", what, path); } } } if (common_dbg > 0) { if (in) { g_debug("[%s] retrieving from \"%s\"%s", what, path, instead); } else if (instead == instead_str) { g_debug("[%s] unable to retrieve: tried %d alternate location%s", what, fvcnt, fvcnt == 1 ? "" : "s"); } else { g_debug("[%s] unable to retrieve: no alternate locations known", what); } } out: HFREE_NULL(path); HFREE_NULL(path_orig); if (in != NULL && chosen != NULL) *chosen = idx; return in; }
/** * Search executable within the user's PATH. * * @return full path if found, NULL otherwise. * The returned string is allocated with halloc(). */ char * file_locate_from_path(const char *argv0) { static bool already_done; char *path; char *tok; char filepath[MAX_PATH_LEN + 1]; char *result = NULL; char *ext = ""; if (is_running_on_mingw() && !is_strsuffix(argv0, (size_t) -1, ".exe")) { ext = ".exe"; } if (filepath_basename(argv0) != argv0) { if (!already_done) { s_warning("can't locate \"%s\" in PATH: name contains '%c' already", argv0, strchr(argv0, G_DIR_SEPARATOR) != NULL ? G_DIR_SEPARATOR : '/'); } result = h_strdup(argv0); goto done; } path = getenv("PATH"); if (NULL == path) { if (!already_done) { s_warning("can't locate \"%s\" in PATH: " "no such environment variable", argv0); } goto done; } /* * On Windows, we need to implicitly add "." to the path if not already * present -- this is done by appending a separator and a dot, not by * checking whether "." is already part of the path. * * The reason is that "." is implied, and also because one may omit the * ".exe" extension when launching a program. This means checks done * in crash_init() for instance to see whether the file listed in * argv[0] exists and which do not account for a missing ".exe" will * attempt to locate the program in the PATH to get a full name and will * fail if we do not add ".". * * On UNIX this cannot happen because there is no hidden extension and * the "." is never made part of the PATH implictly. * * --RAM, 2015-12-06 */ if (is_running_on_mingw()) path = h_strdup_printf("%s%c.", path, *G_SEARCHPATH_SEPARATOR_S); else path = h_strdup(path); path = h_strdup(path); /* FIXME: strtok() is not thread-safe --RAM, 2015-12-06 */ tok = strtok(path, G_SEARCHPATH_SEPARATOR_S); while (NULL != tok) { const char *dir = tok; filestat_t buf; if ('\0' == *dir) dir = "."; concat_strings(filepath, sizeof filepath, dir, G_DIR_SEPARATOR_S, argv0, ext, NULL_PTR); if (-1 != stat(filepath, &buf)) { if (S_ISREG(buf.st_mode) && -1 != access(filepath, X_OK)) { result = h_strdup(filepath); break; } } tok = strtok(NULL, G_SEARCHPATH_SEPARATOR_S); } hfree(path); done: already_done = TRUE; /* No warning on subsequent invocation */ return result; }