Exemple #1
0
/**
 * Free an XML node.
 *
 * This is the user-visible routine that can succeed only if the node is
 * not part of a tree structure.
 */
void
xnode_free(xnode_t *xn)
{
	etree_t t;

	xnode_check(xn);
	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	g_assert(etree_is_standalone(&t, xn));

	switch (xn->type) {
	case XNODE_T_COMMENT:
		HFREE_NULL(xn->u.c.text);
		break;
	case XNODE_T_TEXT:
		HFREE_NULL(xn->u.t.text);
		break;
	case XNODE_T_PI:
		atom_str_free_null(&xn->u.pi.name);
		HFREE_NULL(xn->u.pi.target);
		break;
	case XNODE_T_ELEMENT:
		atom_str_free_null(&xn->u.e.name);
		atom_str_free_null(&xn->u.e.ns_uri);
		nv_table_free_null(&xn->u.e.ns);
		xattr_table_free_null(&xn->u.e.attrs);
		break;
	case XNODE_T_MAX:
		g_assert_not_reached();
	}

	xn->magic = 0;
	WFREE(xn);
}
Exemple #2
0
static int
tth_cache_file_create(const struct tth *tth)
{
	char *pathname;
	int accmode;
	int fd;

	g_return_val_if_fail(tth, -1);

	accmode = O_WRONLY | O_TRUNC;
	pathname = tth_cache_pathname(tth);

	/*
	 * Critical section required since we could have a concurrent thread
	 * deciding to remove empty directories whilst we are attempting
	 * to create a new directory to store the new cached entry!
	 */

	TTH_PATH_LOCK;

	fd = file_create_missing(pathname, accmode, TTH_FILE_MODE);
	if (fd < 0 && ENOENT == errno) {
		char *dir = filepath_directory(pathname);
		if (0 == create_directory(dir, DEFAULT_DIRECTORY_MODE)) {
			fd = file_create(pathname, accmode, TTH_FILE_MODE);
		}
		HFREE_NULL(dir);
	}

	TTH_PATH_UNLOCK;

	HFREE_NULL(pathname);
	return fd;
}
Exemple #3
0
void
statusbar_gui_shutdown(void)
{
    statusbar_gui_free_timeout_list();
	HFREE_NULL(statbar_botstr_new);
	HFREE_NULL(statbar_botstr);
}
Exemple #4
0
G_GNUC_COLD void
tls_global_init(void)
{
    static const struct {
        const char * const name;
        const int major;
        const int minor;
    } f = {
        "tls", 1, 0
    };
    char *cert_file, *key_file;

#if !defined(REMAP_ZALLOC) && !defined(TRACK_MALLOC) && !defined(TRACK_ZALLOC)
    gnutls_global_set_mem_functions(halloc, halloc, NULL, hrealloc, hfree);
#endif

    if (gnutls_global_init()) {
        g_error("gnutls_global_init() failed");
    }

#ifdef USE_TLS_CUSTOM_IO
    gnutls_global_set_log_level(9);
    gnutls_global_set_log_function(tls_log_function);
#endif	/* USE_TLS_CUSTOM_IO */

    get_dh_params();
    gnutls_certificate_allocate_credentials(&cert_cred);

    key_file = make_pathname(settings_config_dir(), "key.pem");
    cert_file = make_pathname(settings_config_dir(), "cert.pem");

    if (file_exists(key_file) && file_exists(cert_file)) {
        int ret;

        ret = gnutls_certificate_set_x509_key_file(cert_cred,
                cert_file, key_file, GNUTLS_X509_FMT_PEM);
        if (ret < 0) {
            g_warning("gnutls_certificate_set_x509_key_file() failed: %s",
                      gnutls_strerror(ret));
        } else {
            gnutls_certificate_set_dh_params(cert_cred, get_dh_params());
        }
    }
    HFREE_NULL(key_file);
    HFREE_NULL(cert_file);

    header_features_add(FEATURES_CONNECTIONS, f.name, f.major, f.minor);
    header_features_add(FEATURES_G2_CONNECTIONS, f.name, f.major, f.minor);
    header_features_add(FEATURES_DOWNLOADS, f.name, f.major, f.minor);
    header_features_add(FEATURES_UPLOADS, f.name, f.major, f.minor);
}
Exemple #5
0
static inline void
magnet_append_item(str_t *s, bool escape_value,
	const char *key, const char *value)
{
	g_return_if_fail(s);
	g_return_if_fail(key);
	g_return_if_fail(value);

	if (0 == str_len(s)) {
		str_cat(s, "magnet:?");
	} else {
		str_putc(s, '&');
	}
	str_cat(s, key);
	str_putc(s, '=');

	if (escape_value) {
		char *escaped;

		escaped = url_escape_query(value);
		str_cat(s, escaped);
		if (escaped != value) {
			HFREE_NULL(escaped);
		}
	} else {
		str_cat(s, value);
	}
}
Exemple #6
0
static struct magnet_source *
magnet_parse_location(const char *uri, const char **error_str)
{
	struct magnet_source *ms;
	const char *p, *host, *host_end;
	host_addr_t addr;
	uint16 port;

	clear_error_str(&error_str);
	g_return_val_if_fail(uri, NULL);

	p = uri;

	p = magnet_parse_host_port(uri, &addr, &port, &host, &host_end, error_str);
	if (NULL == p)
		return NULL;

	ms = magnet_parse_path(p, error_str);
	if (NULL == ms)
		return NULL;

	if (host) {
		char *h = h_strndup(host, host_end - host);
		ms->hostname = atom_str_get(h);
		HFREE_NULL(h);
	}

	ms->addr = addr;
	ms->port = port;

	return ms;
}
Exemple #7
0
/**
 * Fill non-NULL query hash vector for query routing.
 *
 * This needs to be called when st_search() is not called when processing
 * a query, otherwise the qhery hash vector won't be properly initialized
 * and the query would be improperly dropped by qrt_build_query_target(),
 * hence never routed.
 */
void
st_fill_qhv(const char *search_term, query_hashvec_t *qhv)
{
	char *search;
	word_vec_t *wovec;
	guint wocnt;
	guint i;

	if (NULL == qhv)
		return;

	search = UNICODE_CANONIZE(search_term);
	wocnt = word_vec_make(search, &wovec);

	for (i = 0; i < wocnt; i++) {
		if (wovec[i].len >= QRP_MIN_WORD_LENGTH)
			qhvec_add(qhv, wovec[i].word, QUERY_H_WORD);
	}

	if (search != search_term)
		HFREE_NULL(search);

	if (wocnt > 0)
		word_vec_free(wovec, wocnt);
}
Exemple #8
0
/**
 * Destroy a search table.
 */
static void
st_destroy(search_table_t *table)
{
	int i;

	search_table_check(table);

	if (table->bins) {
		for (i = 0; i < table->nbins; i++) {
			struct st_bin *bin = table->bins[i];

			if (bin) {
				bin_destroy(bin);
				WFREE(bin);
			}
		}
		HFREE_NULL(table->bins);
	}

	if (table->all_entries.vals) {
		for (i = 0; i < table->all_entries.nvals; i++) {
			destroy_entry(table->all_entries.vals[i]);
			table->all_entries.vals[i] = NULL;
		}
		bin_destroy(&table->all_entries);
	}
}
Exemple #9
0
/**
 * Destroy a bin.
 *
 * @note Do NOT destroy the st_entry's, since they may be shared.
 */
static void
bin_destroy(struct st_bin *bin)
{
	HFREE_NULL(bin->vals);
	bin->nslots = 0;
	bin->nvals = 0;
}
Exemple #10
0
/**
 * Move SDBM files from "src" to "dst".
 *
 * @param src				the old directory where SDBM files where
 * @param dst				the new directory where SDBM files should be put
 * @param base				the base name of SDBM files
 */
void
dbstore_move(const char *src, const char *dst, const char *base)
{
	char *old_path;
	char *new_path;

	old_path = make_pathname(src, base);
	new_path = make_pathname(dst, base);

	dbstore_move_file(old_path, new_path, DBM_DIRFEXT);
	dbstore_move_file(old_path, new_path, DBM_PAGFEXT);
	dbstore_move_file(old_path, new_path, DBM_DATFEXT);

	HFREE_NULL(old_path);
	HFREE_NULL(new_path);
}
Exemple #11
0
static void
dbstore_move_file(const char *old_path, const char *new_path, const char *ext)
{
	char *old_file = h_strconcat(old_path, ext, (void *) 0);
	char *new_file = h_strconcat(new_path, ext, (void *) 0);

	if (file_exists(old_file)) {
		if (-1 == rename(old_file, new_file)) {
			g_warning("could not rename \"%s\" as \"%s\": %m",
				old_file, new_file);
		}
	}

	HFREE_NULL(old_file);
	HFREE_NULL(new_file);
}
Exemple #12
0
/**
 * Close DM map, keeping the SDBM file around.
 *
 * If the map was held in memory, it is serialized to disk.
 */
void
dbstore_close(dbmw_t *dw, const char *dir, const char *base)
{
	bool ok;
	char *path;

	if (NULL == dw)
		return;

	path = make_pathname(dir, base);

	if (dbstore_debug > 1)
		g_debug("DBSTORE persisting DBMW \"%s\" as %s", dbmw_name(dw), path);

	ok = dbmw_store(dw, path, TRUE);
	HFREE_NULL(path);

	if (dbstore_debug > 0) {
		size_t count = dbmw_count(dw);
		g_debug("DBSTORE %ssucessfully persisted DBMW \"%s\" (%u key%s)",
			ok ? "" : "un", dbmw_name(dw),
			(unsigned) count, 1 == count ? "" : "s");
	}

	dbmw_destroy(dw, TRUE);
}
Exemple #13
0
/**
 * Check whether statusbar items have expired and remove them from the
 * statusbar.
 */
static void
statusbar_gui_clear_timeouts(time_t now)
{
	GSList *sl, *to_remove = NULL;

	for (sl = sl_statusbar_timeouts; sl; sl = g_slist_next(sl)) {
		struct statusbar_timeout *t = sl->data;
		const time_delta_t timeout = t->timeout;

		if (delta_time(now, t->stamp) > timeout)
			to_remove = g_slist_prepend(to_remove, t);
	}

	for (sl = to_remove; sl; sl = g_slist_next(sl)) {
		statusbar_gui_free_timeout(sl->data);
	}
	g_slist_free(to_remove);

	/*
	 * When there are no more timeouts left, and there's a pending
	 * new statusbar string to display, pop the old one and add the new.
	 *		--RAM, 27/06/2002
	 */

	if (sl_statusbar_timeouts == NULL && statbar_botstr_new) {
    	gtk_statusbar_pop(statusbar_get(), scid_bottom);
		HFREE_NULL(statbar_botstr);
		statbar_botstr = statbar_botstr_new;
		statbar_botstr_new = NULL;
		statusbar_gui_push(SB_MESSAGE, scid_bottom, 0, "%s", statbar_botstr);
	}
}
Exemple #14
0
/**
 * Loads the geo-ip.txt into memory.
 *
 * Choosing the first file we find among the several places we look at,
 * typically:
 *
 *		-# ~/.gtk-gnutella/geo-ip.txt
 *		-# /usr/share/gtk-gnutella/geo-ip.txt
 *		-# /home/src/gtk-gnutella/geo-ip.txt
 *
 * The selected file will then be monitored and a reloading will occur
 * shortly after a modification.
 */
static void
gip_retrieve(unsigned n)
{
	FILE *f;
	int idx;
	char *filename;
	file_path_t fp[4];
	unsigned length;

	length = settings_file_path_load(fp, gip_source[n].file, SFP_DFLT);

	g_assert(length <= N_ITEMS(fp));

	f = file_config_open_read_norename_chosen(
			gip_source[n].what, fp, length, &idx);

	if (NULL == f)
	   return;

	filename = make_pathname(fp[idx].dir, fp[idx].name);
	watcher_register(filename, gip_changed, uint_to_pointer(n));
	HFREE_NULL(filename);

	gip_load(f, n);
	fclose(f);
}
Exemple #15
0
/**
 * Add an entry to the persistent cache.
 */
static void
add_persistent_cache_entry(const char *filename, filesize_t size,
	time_t mtime, const struct sha1 *sha1, const struct tth *tth)
{
	char *pathname;
	FILE *f;

	pathname = make_pathname(settings_config_dir(), "sha1_cache");
	f = file_fopen(pathname, "a");
	if (f) {
		filestat_t sb;

		/*
		 * If we're adding the very first entry (file empty), then emit header.
		 */

		if (fstat(fileno(f), &sb)) {
			g_warning("%s(): could not stat \"%s\": %m", G_STRFUNC, pathname);
		} else {
			if (0 == sb.st_size) {
				fputs(sha1_persistent_cache_file_header, f);
			}
			cache_entry_print(f, filename, sha1, tth, size, mtime);
		}
		fclose(f);
	} else {
		g_warning("%s(): could not open \"%s\": %m", G_STRFUNC, pathname);
	}
	HFREE_NULL(pathname);
}
Exemple #16
0
/**
 * Pick host at random among the host array.
 *
 * @return TRUE if OK.
 */
static bool
uhc_pick(void)
{
	bool success = FALSE;
	char *uhc;

	uhc = uhc_get_next();
	if (NULL == uhc) {
		if (GNET_PROPERTY(bootstrap_debug))
			g_warning("BOOT ran out of UHCs, switching to GHCs");
		ghc_get_hosts();
		goto finish;
	}

	if (!uhc_get_host_port(uhc, &uhc_ctx.host, &uhc_ctx.port)) {
		g_warning("cannot parse UDP host cache \"%s\"", uhc);
		goto finish;
	}

	/*
	 * Give GUI feedback.
	 */
	{
		char msg[256];

		str_bprintf(msg, sizeof msg, _("Looking for UDP host cache %s"), uhc);
		gcu_statusbar_message(msg);
	}
	success = TRUE;

finish:
	HFREE_NULL(uhc);
	return success;
}
Exemple #17
0
/**
 * @return The number of leaves or zero if unknown.
 */
size_t
tth_cache_lookup(const struct tth *tth, filesize_t filesize)
{
	size_t expected, leave_count = 0;
	
	g_return_val_if_fail(tth, 0);

	expected = tt_good_node_count(filesize);
	if (expected > 1) {
		filestat_t sb;
		char *pathname;

		pathname = tth_cache_pathname(tth);
		if (stat(pathname, &sb)) {
			leave_count = 0;
			if (ENOENT != errno) {
				g_warning("%s(%s): stat(\"%s\") failed: %m",
					G_STRFUNC, tth_base32(tth), pathname);
			}
		} else {
			leave_count = tth_cache_leave_count(tth, &sb);
		}
		HFREE_NULL(pathname);
	} else {
		leave_count = 1;
	}
	return expected != leave_count ? 0 : leave_count;
}
Exemple #18
0
/**
 * Loads the spam.txt into memory.
 *
 * The selected file will then be monitored and a reloading will occur
 * shortly after a modification.
 */
static void
spam_retrieve(void)
{
	file_path_t fp[4];
	FILE *f;
	int idx;
	char *tmp;
	unsigned length = 0;

	file_path_set(&fp[length++], settings_config_dir(), spam_text_file);
	file_path_set(&fp[length++], PRIVLIB_EXP, spam_text_file);

#ifndef OFFICIAL_BUILD
	file_path_set(&fp[length++], PACKAGE_EXTRA_SOURCE_DIR, spam_text_file);
#endif	/* !OFFICIAL_BUILD */

	tmp = get_folder_path(PRIVLIB_PATH, NULL);
	if (tmp != NULL)
		file_path_set(&fp[length++], tmp, spam_text_file);

	g_assert(length <= G_N_ELEMENTS(fp));

	f = file_config_open_read_norename_chosen(spam_what, fp, length, &idx);
	if (f != NULL) {
		spam_retrieve_from_file(f, fp[idx].dir, fp[idx].name);
		fclose(f);
	}

	HFREE_NULL(tmp);
}
Exemple #19
0
/**
 * Initialize RX dumping.
 *
 * @return TRUE if initialized.
 */
static gboolean
dump_initialize(struct dump *dump)
{
	char *pathname;

	if (dump->initialized)
		return TRUE;

	pathname = make_pathname(settings_config_dir(), dump->filename);
	dump->fd = file_open_missing(pathname, O_WRONLY | O_APPEND | O_NONBLOCK);
	HFREE_NULL(pathname);

	/*
	 * If the dump "file" is actually a named pipe, we'd block quickly
	 * if there was no reader.  So set the file as non-blocking and
	 * we'll disable dumping as soon as we can't write all the data
	 * we want.
	 */

	if (dump->fd < 0) {
		g_warning("can't open %s -- disabling dumping", dump->filename);
		dump_disable(dump);
		return FALSE;
	}

	fd_set_nonblocking(dump->fd);

	dump->slist = slist_new();
	dump->fill = 0;
	dump->initialized = TRUE;

	return TRUE;
}
Exemple #20
0
/**
 * Same as watcher_unregister() but a path, i.e. a (dir, base) tuple is
 * given instead of a complete filename.
 */
void
watcher_unregister_path(const file_path_t *fp)
{
	char *path;

	path = make_pathname(fp->dir, fp->name);
	watcher_unregister(path);
	HFREE_NULL(path);
}
Exemple #21
0
/**
 * Same as watcher_register() but a path, i.e. a (dir, base) tuple is
 * given instead of a complete filename.
 */
void
watcher_register_path(const file_path_t *fp, watcher_cb_t cb, void *udata)
{
	char *path;

	path = make_pathname(fp->dir, fp->name);
	watcher_register(path, cb, udata);
	HFREE_NULL(path);
}
Exemple #22
0
/**
 * Frees the key/values from the headers hash.
 */
static gboolean
free_header_data(gpointer key, gpointer value, gpointer unused_udata)
{
	(void) unused_udata;

	HFREE_NULL(key);			/* XXX if shared, don't do that */
	str_destroy(value);
	return TRUE;
}
Exemple #23
0
/**
 * Free descriptor managing large keys and values.
 */
void
big_free(DBM *db)
{
	DBMBIG *dbg = db->big;

	if (NULL == dbg)
		return;

	if (common_stats)
		log_bigstats(db);

	big_datfile_free_null(&dbg->file);
	WFREE_NULL(dbg->bitbuf, BIG_BLKSIZE);
	HFREE_NULL(dbg->bitcheck);
	HFREE_NULL(dbg->scratch);
	fd_forget_and_close(&dbg->fd);
	WFREE(dbg);
}
Exemple #24
0
/**
 * Free an attribute key/value.
 */
static void
xattr_free(struct xattr *xa)
{
	g_assert(xa != NULL);

	atom_str_free_null(&xa->uri);
	atom_str_free_null(&xa->local);
	HFREE_NULL(xa->value);
	WFREE(xa);
}
Exemple #25
0
/* Display XML data from the result if any */
static void
search_set_xml_metadata(const record_t *rc)
{
	char *indented;

	indented = (rc && rc->xml) ? xml_indent(rc->xml) : NULL;
	set_text_buffer(gui_main_window_lookup("text_result_info_xml"),
		EMPTY_STRING(indented));
	HFREE_NULL(indented);
}
Exemple #26
0
/**
 * Dispose of the header field.
 */
static void
hfield_free(header_field_t *h)
{
	header_field_check(h);

	slist_free_all(&h->lines, hfield_free_item);
	HFREE_NULL(h->name);
	h->magic = 0;
	WFREE(h);
}
Exemple #27
0
/**
 * Free parsed token.
 */
static void
ctl_token_free(struct ctl_tok *tok)
{
	g_assert(tok != NULL);

	if (CTL_TOK_ID == tok->type) {
		HFREE_NULL(tok->val.s);
	}
	WFREE(tok);
}
Exemple #28
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;
}
Exemple #29
0
void
tth_cache_remove(const struct tth *tth)
{
	char *pathname;

	g_return_if_fail(tth);

	pathname = tth_cache_pathname(tth);
	unlink(pathname);
	HFREE_NULL(pathname);
}
Exemple #30
0
/**
 * Free the file information.
 */
static void
big_datfile_free_null(struct datfile **file_ptr)
{
	struct datfile *file = *file_ptr;

	if (file != NULL) {
		HFREE_NULL(file->datname);
		WFREE(file);
		*file_ptr = NULL;
	}
}