Esempio n. 1
0
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]);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
/**
 * 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;
}
Esempio n. 5
0
/**
 * 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;
}
Esempio n. 6
0
/**
 * 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;
}