Esempio n. 1
0
/**
 * Get the full program path.
 *
 * @return a newly allocated string (through halloc()) that points to the
 * path of the program being run, NULL if we can't compute a suitable path.
 */
char *
file_program_path(const char *argv0)
{
	filestat_t buf;
	char *file = deconstify_char(argv0);
	char filepath[MAX_PATH_LEN + 1];

	if (is_running_on_mingw() && !is_strsuffix(argv0, (size_t) -1, ".exe")) {
		concat_strings(filepath, sizeof filepath, argv0, ".exe", NULL_PTR);
	} else {
		clamp_strcpy(filepath, sizeof filepath, argv0);
	}

	if (-1 == stat(filepath, &buf)) {
		int saved_errno = errno;
		file = file_locate_from_path(argv0);
		if (NULL == file) {
			errno = saved_errno;
			s_warning("%s(): could not stat() \"%s\": %m", G_STRFUNC, filepath);
			return NULL;
		}
	}

	if (file != NULL && file != argv0)
		return file;		/* Allocated by file_locate_from_path() */

	return h_strdup(filepath);
}
Esempio n. 2
0
/**
 * Get field value, or NULL if not present.  The value returned is a
 * pointer to the internals of the header structure, so it must not be
 * kept around.
 */
char *
header_get(const header_t *o, const char *field)
{
	str_t *v;

	header_check(o);

	if (o->headers) {
		v = htable_lookup(o->headers, deconstify_char(field));
	} else {
		v = NULL;
	}
	return str_2c(v);
}
Esempio n. 3
0
static void
search_stats_notify_routed(query_type_t unused_type, const char *unused_search,
                           const host_addr_t addr, guint16 port)
{
    word_vec_t wovec;

    (void) unused_type;
    (void) unused_search;

    wovec.word = deconstify_char(host_addr_port_to_string(addr, port));
    wovec.len = strlen(wovec.word);
    wovec.amount = 1;

    search_stats_tally(&wovec);
}
Esempio n. 4
0
/**
 * Get field value, or NULL if not present.  The value returned is a
 * pointer to the internals of the header structure, so it must not be
 * kept around.
 *
 * If the len_ptr pointer is not NULL, it is filled with the length
 * of the header string.
 */
char *
header_get_extended(const header_t *o, const char *field, size_t *len_ptr)
{
	str_t *v;

	header_check(o);

	if (o->headers) {
		v = htable_lookup(o->headers, deconstify_char(field));
	} else {
		v = NULL;
	}
	if (v && len_ptr != NULL) {
		*len_ptr = str_len(v);
	}
	return str_2c(v);
}
Esempio n. 5
0
/**
 * Writes the browse host data of the context ``ctx'' to the buffer
 * ``dest''. This must be called multiple times to retrieve the complete
 * data until zero is returned i.e., the end of file is reached.
 *
 * This routine deals with HTML data generation.
 *
 * @param ctx an initialized browse host context.
 * @param dest the destination buffer.
 * @param size the amount of bytes ``dest'' can hold.
 *
 * @return -1 on failure, zero at the end-of-file condition or if size
 *         was zero. On success, the amount of bytes copied to ``dest''
 *         is returned.
 */
static ssize_t
browse_host_read_html(struct special_upload *ctx,
	void *const dest, size_t size)
{
	static const char header[] =
		"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\r\n"
		"<html>\r\n"
		"<head>\r\n"
		"<title>Browse Host</title>\r\n"
		"</head>\r\n"
		"<body>\r\n";
	static const char trailer[] = "</ul>\r\n</body>\r\n</html>\r\n";
	struct browse_host_upload *bh = cast_to_browse_host_upload(ctx);
	char *p = dest;

	g_assert(NULL != bh);
	g_assert(NULL != dest);
	g_assert(size <= INT_MAX);

	g_assert(UNSIGNED(bh->state) < NUM_BH_STATES);
	g_assert(bh->b_size <= INT_MAX);
	g_assert(bh->b_offset <= bh->b_size);

	do {
		switch (bh->state) {
		case BH_STATE_HEADER:
			if (!bh->b_data) {
				bh->b_data = header;
				bh->b_size = CONST_STRLEN(header);
			}
			p += browse_host_read_data(bh, p, &size);
			if (bh->b_size == bh->b_offset)
				browse_host_next_state(bh, BH_STATE_LIBRARY_INFO);
			break;

		case BH_STATE_LIBRARY_INFO:
			if (!bh->b_data) {
				bh->w_buf_size = w_concat_strings(&bh->w_buf,
					"<h1>", product_get_name(), "</h1>\r\n"
					"<h3>", version_get_string(),
				   	" sharing ",
					uint64_to_string(shared_files_scanned()),
					" file",
					shared_files_scanned() == 1 ? "" : "s",
					" ",
					short_kb_size(shared_kbytes_scanned(),
						GNET_PROPERTY(display_metric_units)),
					" total</h3>\r\n"
					"<ul>\r\n", (void *) 0);
				bh->b_data = bh->w_buf;
				bh->b_size = bh->w_buf_size - 1; /* minus trailing NUL */
				bh->b_offset = 0;
			}
			p += browse_host_read_data(bh, p, &size);
			if (bh->b_size == bh->b_offset)
				browse_host_next_state(bh, BH_STATE_FILES);
			break;

		case BH_STATE_TRAILER:
			if (!bh->b_data) {
				bh->b_data = trailer;
				bh->b_size = CONST_STRLEN(trailer);
			}
			p += browse_host_read_data(bh, p, &size);
			if (bh->b_size == bh->b_offset)
				browse_host_next_state(bh, BH_STATE_EOF);
			break;

		case BH_STATE_FILES:
			if (bh->b_data && bh->b_size == bh->b_offset) {
				g_assert(bh->w_buf == bh->b_data);
				wfree(bh->w_buf, bh->w_buf_size);
				bh->w_buf = NULL;
				bh->w_buf_size = 0;
				bh->b_data = NULL;
			}

			if (!bh->b_data) {
				const shared_file_t *sf;

				bh->file_index++;
				sf = shared_file_sorted(bh->file_index);
				if (!sf) {
				   	if (bh->file_index > shared_files_scanned())
						browse_host_next_state(bh, BH_STATE_TRAILER);
					/* Skip holes in the file_index table */
				} else if (SHARE_REBUILDING == sf) {
					browse_host_next_state(bh, BH_STATE_REBUILDING);
				} else {
					const char * const name_nfc = shared_file_name_nfc(sf);
					const filesize_t file_size = shared_file_size(sf);
					size_t html_size;
					char *html_name;

					{
						const char *dir;
						char *name;
						
						dir = shared_file_relative_path(sf);
						if (dir) {
							name = h_strconcat(dir, "/", name_nfc, (void *) 0);
						} else {
							name = deconstify_char(name_nfc);
						}

						html_size = 1 + html_escape(name, NULL, 0);
						html_name = walloc(html_size);
						html_escape(name, html_name, html_size);
						if (name != name_nfc) {
							HFREE_NULL(name);
						}
					}

					if (sha1_hash_available(sf)) {
						const struct sha1 *sha1 = shared_file_sha1(sf);

						bh->w_buf_size = w_concat_strings(&bh->w_buf,
							"<li><a href=\"/uri-res/N2R?urn:sha1:",
							sha1_base32(sha1),
							"\">", html_name, "</a>&nbsp;[",
							short_html_size(file_size,
								GNET_PROPERTY(display_metric_units)),
							"]</li>\r\n",
							(void *) 0);
					} else {
						char *escaped;

						escaped = url_escape(name_nfc);
						bh->w_buf_size = w_concat_strings(&bh->w_buf,
							"<li><a href=\"/get/",
							uint32_to_string(shared_file_index(sf)),
							"/", escaped, "\">", html_name, "</a>"
							"&nbsp;[",
							short_html_size(file_size,
								GNET_PROPERTY(display_metric_units)),
							"]</li>\r\n", (void *) 0);

						if (escaped != name_nfc) {
							HFREE_NULL(escaped);
						}
					}

					wfree(html_name, html_size);
					bh->b_data = bh->w_buf;
					bh->b_size = bh->w_buf_size - 1; /* minus trailing NUL */
					bh->b_offset = 0;
				}
			}

			if (bh->b_data)
				p += browse_host_read_data(bh, p, &size);

			break;

		case BH_STATE_REBUILDING:
			if (!bh->b_data) {
				static const char msg[] =
					"<li>"
						"<b>"
							"The library is currently being rebuild. Please, "
							"try again in a moment."
						"</b>"
					"</li>";

				bh->b_data = msg;
				bh->b_size = CONST_STRLEN(msg);
			}
			p += browse_host_read_data(bh, p, &size);
			if (bh->b_size == bh->b_offset)
				browse_host_next_state(bh, BH_STATE_TRAILER);
			break;

		case BH_STATE_EOF:
			return p - cast_to_char_ptr(dest);

		case NUM_BH_STATES:
			g_assert_not_reached();
		}
	} while (size > 0);

	return p - cast_to_char_ptr(dest);
}