static PyObject* py_product_get_name(PyObject* self, PyObject* args) { unsigned PY_LONG_LONG product; const char* product_name; if (!PyArg_ParseTuple(args, "K", &product)) { return NULL; } product_name = product_get_name((jobject) product); return PyUnicode_FromString(product_name); }
/** * Generates the version string. This function does not require any * initialization, thus may be called very early e.g., for showing * version information if the executable was invoked with --version * as argument. * * @return A pointer to a static buffer holding the version string. */ G_GNUC_COLD const char * version_build_string(void) { static bool initialized; static char buf[128]; if (!initialized) { const char *sysname = "Unknown"; const char *machine = NULL; initialized = TRUE; #ifdef HAS_UNAME { static struct utsname un; /* Must survive this scope */ if (-1 != uname(&un)) { sysname = un.sysname; machine = un.machine; } else { s_carp("uname() failed: %m"); } } #endif /* HAS_UNAME */ str_bprintf(buf, sizeof buf, "%s/%s%s (%s; %s; %s%s%s)", product_get_name(), product_get_version(), product_get_build_full(), product_get_date(), product_get_interface(), sysname, machine && machine[0] ? " " : "", machine ? machine : ""); } return buf; }
/** * 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> [", 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>" " [", 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); }
/** * Initialize version string. */ G_GNUC_COLD void version_init(void) { time_t now; version_string = ostrdup_readonly(version_build_string()); now = tm_time(); { bool ok; const char *end; ok = version_parse(version_string, &our_version, &end); g_assert(ok); ok = version_ext_parse(end, &our_ext_version); g_assert(ok); } g_info("%s", version_string); version_stamp(version_string, &our_version); g_assert(our_version.timestamp != 0); { char buf[128]; str_bprintf(buf, sizeof(buf), "%s/%s%s (%s)", product_get_name(), product_get_version(), product_get_build_full(), product_get_date()); version_short_string = ostrdup_readonly(buf); } last_rel_version = our_version; /* struct copy */ last_dev_version = our_version; /* struct copy */ our_ext_version.version = our_version; /* struct copy */ /* * The version code is a one-byte encoding of the year/month, since * what matters is not much the version number as to the age of the * servent... The version code is transmitted in pongs via GGEP "VC". */ if (our_version.timestamp) { struct tm *tmp = localtime(&our_version.timestamp); version_code = (((tmp->tm_year + 1900 - 2000) & 0x0f) << 4) | (tmp->tm_mon + 1); } else version_code = 0; /* * The property system is not up when this is called, but we need * to set this variable correctly. */ if ( tok_is_ancient(now) || delta_time(now, our_version.timestamp) > VERSION_ANCIENT_WARN ) { *deconstify_bool(&GNET_PROPERTY(ancient_version)) = TRUE; } }