/** * Updates the horizon statistics in the statusbar. * * This is an event-driven callback called from the HSEP code * using the event listener framework. In addition to taking into account * the HSEP information, the number of established non-HSEP nodes and * their library size (if provided) are added to the values displayed. */ void gnet_stats_gui_horizon_update(hsep_triple *table, guint32 triples) { const guint32 hops = 4U; /* must be <= HSEP_N_MAX */ guint64 val; hsep_triple other; if (triples <= hops) /* should not happen */ return; g_assert((gint32) triples > 0); guc_hsep_get_non_hsep_triple(&other); /* * Update the 3 labels in the statusbar with the horizon values for a * distance of 'hops' hops. */ val = table[hops][HSEP_IDX_NODES] + other[HSEP_IDX_NODES]; gtk_label_printf(GTK_LABEL( gui_main_window_lookup("label_statusbar_horizon_node_count")), "%s %s", uint64_to_string(val), NG_("node", "nodes", val)); val = table[hops][HSEP_IDX_FILES] + other[HSEP_IDX_FILES]; gtk_label_printf(GTK_LABEL( gui_main_window_lookup("label_statusbar_horizon_file_count")), "%s %s", uint64_to_string(val), NG_("file", "files", val)); val = table[hops][HSEP_IDX_KIB] + other[HSEP_IDX_KIB]; gtk_label_printf(GTK_LABEL( gui_main_window_lookup("label_statusbar_horizon_kb_count")), "%s", short_kb_size(val, show_metric_units())); }
/** * Destroy the DBM wrapper, optionally closing the underlying DB map. */ void dbmw_destroy(dbmw_t *dw, bool close_map) { dbmw_check(dw); if (common_stats) { s_debug("DBMW destroying \"%s\" with %s back-end " "(read cache hits = %.2f%% on %s request%s, " "write cache hits = %.2f%% on %s request%s)", dw->name, dbmw_map_type(dw) == DBMAP_SDBM ? "sdbm" : "map", dw->r_hits * 100.0 / MAX(1, dw->r_access), uint64_to_string(dw->r_access), plural(dw->r_access), dw->w_hits * 100.0 / MAX(1, dw->w_access), uint64_to_string2(dw->w_access), plural(dw->w_access)); } if (dbg_ds_debugging(dw->dbg, 1, DBG_DSF_DESTROY)) { dbg_ds_log(dw->dbg, dw, "%s: with %s back-end " "(read cache hits = %.2f%% on %s request%s, " "write cache hits = %.2f%% on %s request%s)", G_STRFUNC, dbmw_map_type(dw) == DBMAP_SDBM ? "sdbm" : "map", dw->r_hits * 100.0 / MAX(1, dw->r_access), uint64_to_string(dw->r_access), plural(dw->r_access), dw->w_hits * 100.0 / MAX(1, dw->w_access), uint64_to_string2(dw->w_access), plural(dw->w_access)); } /* * If we close the map and we're volatile, there's no need to flush * the cache as the data is going to be gone soon anyway. */ if (!close_map || !dw->is_volatile) { dbmw_sync(dw, DBMW_SYNC_CACHE); } dbmw_clear_cache(dw); hash_list_free(&dw->keys); map_destroy(dw->values); if (dw->mb) pmsg_free(dw->mb); bstr_free(&dw->bs); if (close_map) dbmap_destroy(dw->dm); WFREE_TYPE_NULL(dw->dbmap_dbg); dw->magic = 0; WFREE(dw); }
/** * Called when a row of the upload stats should be updated */ void upload_stats_gui_update_model(struct ul_stats *us) { GtkCList *clist = clist_ul_stats(); enum c_us i; int row; row = ul_stats_get_row(us); g_return_if_fail(row >= 0); for (i = 0; i < c_us_num; i++) { const char *text = NULL; char tmpstr[16]; switch (i) { case c_us_filename: case c_us_size: /* Never updated, only initialized */ continue; case c_us_attempts: text = uint64_to_string(us->attempts); break; case c_us_complete: text = uint64_to_string(us->complete); break; case c_us_norm: gm_snprintf(tmpstr, sizeof tmpstr, "%.3f", us->norm); text = tmpstr; break; case c_us_rtime: text = us->rtime ? timestamp_to_string(us->rtime) : ""; break; case c_us_dtime: text = us->dtime ? timestamp_to_string(us->dtime) : ""; break; case c_us_num: text = NULL; g_assert_not_reached(); } gtk_clist_set_text(clist, row, i, text); } /* FIXME: use auto-sort? */ if (0 == clist->freeze_count) { gtk_clist_sort(clist); clist_sync_rows(clist, on_clist_ul_stats_row_moved); } }
dynamic_string uint_to_string(uint64_t value) { const uint32_t cBufSize = 32; char buf[cBufSize]; uint64_to_string(value, buf, cBufSize); return dynamic_string(buf); }
/** * Check whether key already holds data from the creator. * * @param id the primary key * @param cid the secondary key (creator's id) * @param store whether to increment the store request count * * @return 64-bit DB key for the value if it does, 0 if key either does not * exist yet or does not hold data from the creator. */ uint64 keys_has(const kuid_t *id, const kuid_t *cid, bool store) { struct keyinfo *ki; struct keydata *kd; uint64 dbkey; ki = hikset_lookup(keys, id); if (ki == NULL) return 0; if (store) ki->store_requests++; kd = get_keydata(id); if (kd == NULL) return 0; g_assert(ki->values == kd->values); dbkey = lookup_secondary(kd, cid); if (GNET_PROPERTY(dht_storage_debug) > 15) { g_debug("DHT lookup secondary for %s/%s => dbkey %s", kuid_to_hex_string(id), kuid_to_hex_string2(cid), uint64_to_string(dbkey)); } return dbkey; }
/** * Record a new leak of `size' bytes allocated at `file', line `line'. */ void leak_add(leak_set_t *ls, size_t size, const char *file, int line) { char key[1024]; struct leak_record *lr; bool found; void *v; leak_set_check(ls); g_assert(file); g_assert(line >= 0); concat_strings(key, sizeof key, file, ":", uint64_to_string(line), (void *) 0); found = htable_lookup_extended(ls->places, key, NULL, &v); if (found) { lr = v; lr->size += size; lr->count++; } else { XPMALLOC(lr); lr->size = size; lr->count = 1; htable_insert(ls->places, xstrdup(key), lr); } }
static void cell_renderer_func(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer udata) { static const GValue zero_value; const struct upload_data *data; const gchar *text = NULL; gchar buf[64]; GValue value; if (!gtk_tree_view_column_get_visible(column)) return; value = zero_value; gtk_tree_model_get_value(model, iter, 0, &value); data = g_value_get_pointer(&value); switch ((enum c_us) GPOINTER_TO_UINT(udata)) { case c_us_filename: text = data->filename; break; case c_us_size: text = short_size(data->us->size, show_metric_units()); break; case c_us_attempts: text = uint64_to_string(data->us->attempts); break; case c_us_complete: text = uint64_to_string(data->us->attempts); break; case c_us_norm: str_bprintf(buf, sizeof buf, "%1.3f", data->us->norm); text = buf; break; case c_us_rtime: text = data->us->rtime ? timestamp_to_string(data->us->rtime) : NULL; break; case c_us_dtime: text = data->us->dtime ? timestamp_to_string(data->us->dtime) : NULL; break; case c_us_num: g_assert_not_reached(); } g_object_set(cell, "text", text, (void *) 0); }
static void hsep_dump_table(void) { unsigned int i; printf("HSEP: Reachable nodes (1-%d hops): ", HSEP_N_MAX); for (i = 1; i < G_N_ELEMENTS(hsep_global_table); i++) printf("%s ", uint64_to_string(hsep_global_table[i][HSEP_IDX_NODES])); printf("\nHSEP: Reachable files (1-%d hops): ", HSEP_N_MAX); for (i = 1; i < G_N_ELEMENTS(hsep_global_table); i++) printf("%s ", uint64_to_string(hsep_global_table[i][HSEP_IDX_FILES])); printf("\nHSEP: Reachable KiB (1-%d hops): ", HSEP_N_MAX); for (i = 1; i < G_N_ELEMENTS(hsep_global_table); i++) printf("%s ", uint64_to_string(hsep_global_table[i][HSEP_IDX_KIB])); printf("\n"); hsep_sanity_check(); }
DecimalDecNumber::DecimalDecNumber(uint64 rhs) { decContextDefault(&m_context, DEC_INIT_BASE); // initialize m_context.traps = 0; // no traps, thank you m_context.digits = DECNUMDIGITS; // set precision if (rhs <= std::numeric_limits<uint>::max()) { decNumberFromUInt32(&m_value, static_cast<uint>(rhs)); } else { char buffer[64]; uint64_to_string(rhs, buffer); decNumberFromString(&m_value, buffer, &m_context); } }
/** * Delete known-to-be existing token data for specified KUID from database. */ static void delete_tokdata(const kuid_t *id) { dbmw_delete(db_tokdata, id); gnet_stats_dec_general(GNR_DHT_CACHED_TOKENS_HELD); if (GNET_PROPERTY(dht_tcache_debug) > 2) g_debug("DHT TCACHE security token from %s reclaimed", kuid_to_hex_string(id)); if (GNET_PROPERTY(dht_tcache_debug_flags) & DBG_DSF_USR1) { g_debug("DHT TCACHE %s: stats=%s, count=%zu, id=%s", G_STRFUNC, uint64_to_string( gnet_stats_get_general(GNR_DHT_CACHED_TOKENS_HELD)), dbmw_count(db_tokdata), kuid_to_hex_string(id)); } }
static void upload_stats_dump_item(gpointer p, gpointer user_data) { const shared_file_t *sf; FILE *out = user_data; struct ul_stats *s = p; char rtime_buf[TIME_T_DEC_BUFLEN]; char dtime_buf[TIME_T_DEC_BUFLEN]; const char *pathname; char *escaped; g_assert(NULL != s); sf = s->sha1 ? shared_file_by_sha1(s->sha1) : NULL; sf = SHARE_REBUILDING != sf ? sf : NULL; if (sf) { pathname = shared_file_path(sf); } else { pathname = s->pathname; } escaped = url_escape_cntrl(pathname); time_t_to_string_buf(s->rtime, rtime_buf, sizeof rtime_buf); time_t_to_string_buf(s->dtime, dtime_buf, sizeof dtime_buf); fprintf(out, "%s\t%s\t%u\t%u\t%lu\t%lu\t%s\t%s\t%s\n", escaped, uint64_to_string(s->size), s->attempts, s->complete, (unsigned long) (s->bytes_sent >> 32), (unsigned long) (s->bytes_sent & 0xffffffff), rtime_buf, dtime_buf, s->sha1 ? sha1_base32(s->sha1) : "*"); if (escaped != pathname) { /* File had escaped chars */ HFREE_NULL(escaped); } }
void bitzi_gui_update(const bitzi_data_t *bitzi_data) { guint32 bitzi_debug; g_assert(bitzi_data != NULL); gnet_prop_get_guint32_val(PROP_BITZI_DEBUG, &bitzi_debug); if (bitzi_debug > 10) g_debug("bitzi_gui_update: data %p, size %s, " "goodness %f, judgment %d, type %s, details %s", cast_to_gconstpointer(bitzi_data), uint64_to_string(bitzi_data->size), bitzi_data->goodness, bitzi_data->judgment, NULL_STRING(bitzi_data->mime_type), NULL_STRING(bitzi_data->mime_desc)); /* Update the various GUI elements */ search_gui_metadata_update(bitzi_data); }
/** * Destroy the DBM wrapper, optionally closing the underlying DB map. */ void dbmw_destroy(dbmw_t *dw, gboolean close_map) { dbmw_check(dw); if (common_stats) g_debug("DBMW destroying \"%s\" with %s back-end " "(read cache hits = %.2f%% on %s request%s, " "write cache hits = %.2f%% on %s request%s)", dw->name, dbmw_map_type(dw) == DBMAP_SDBM ? "sdbm" : "map", dw->r_hits * 100.0 / MAX(1, dw->r_access), uint64_to_string(dw->r_access), 1 == dw->r_access ? "" : "s", dw->w_hits * 100.0 / MAX(1, dw->w_access), uint64_to_string2(dw->w_access), 1 == dw->w_access ? "" : "s"); /* * If we close the map and we're volatile, there's no need to flush * the cache as the data is going to be gone soon anyway. */ if (!close_map || !dw->is_volatile) { dbmw_sync(dw, DBMW_SYNC_CACHE); } dbmw_clear_cache(dw); hash_list_free(&dw->keys); map_destroy(dw->values); if (dw->mb) pmsg_free(dw->mb); bstr_free(&dw->bs); if (close_map) dbmap_destroy(dw->dm); dw->magic = 0; WFREE(dw); }
/** * Map iterator to record security tokens in the database. */ static void record_token(void *key, void *value, void *unused_u) { kuid_t *id = key; lookup_token_t *ltok = value; struct tokdata td; (void) unused_u; td.last_update = ltok->retrieved; td.length = ltok->token->length; td.token = td.length ? wcopy(ltok->token->v, td.length) : NULL; if (GNET_PROPERTY(dht_tcache_debug) > 4) { char buf[80]; bin_to_hex_buf(td.token, td.length, buf, sizeof buf); g_debug("DHT TCACHE adding security token for %s: %u-byte \"%s\"", kuid_to_hex_string(id), td.length, buf); } /* * Data is put in the DBMW cache and the dynamically allocated token * will be freed via free_tokdata() when the cached entry is released. */ if (!dbmw_exists(db_tokdata, id->v)) gnet_stats_inc_general(GNR_DHT_CACHED_TOKENS_HELD); dbmw_write(db_tokdata, id->v, &td, sizeof td); if (GNET_PROPERTY(dht_tcache_debug_flags) & DBG_DSF_USR1) { g_debug("DHT TCACHE %s: stats=%s, count=%zu, id=%s", G_STRFUNC, uint64_to_string( gnet_stats_get_general(GNR_DHT_CACHED_TOKENS_HELD)), dbmw_count(db_tokdata), kuid_to_hex_string(id)); } }
void hsep_notify_shared(uint64 own_files, uint64 own_kibibytes) { /* check for change */ if ( own_files != hsep_own[HSEP_IDX_FILES] || own_kibibytes != hsep_own[HSEP_IDX_KIB] ) { if (GNET_PROPERTY(hsep_debug)) { g_debug("HSEP: Shared files changed to %s (%s KiB)", uint64_to_string(own_files), uint64_to_string2(own_kibibytes)); } hsep_own[HSEP_IDX_FILES] = own_files; hsep_own[HSEP_IDX_KIB] = own_kibibytes; /* * We could send a HSEP message to all nodes now, but these changes * will propagate within at most HSEP_MSG_INTERVAL + HSEP_MSG_SKEW * seconds anyway. */ } }
/** * Decodes "chunked" data. * * The function returns as soon as it needs more data to proceed, on * error, if the state CHUNK_STATE_END was reached, or if the state * CHUNK_STATE_DATA was reached. In the latter case the chunk payload * itself must be consumed and this function must not be called again * until the state CHUNK_STATE_DATA_CRLF is reached. * * @param rx the current RX driver. * @param src the chunk data. * @param size no document. * @param p_error_str if not NULL and parse_chunk() fails, it will point * to an informational error message. * * @return 0 on failure; non-zero amount of consumed bytes on success. */ static size_t parse_chunk(rxdrv_t *rx, const char *src, size_t size, const char **p_error_str) { struct attr *attr = rx->opaque; const char *error_str; size_t len; g_assert(attr); g_assert(src); g_assert(size > 0); g_assert(attr->state < NUM_CHUNK_STATES); g_assert(0 == attr->data_remain); len = size; do { switch (attr->state) { case CHUNK_STATE_DATA_CRLF: /* The chunk-data must be followed by a CRLF */ while (len > 0) { uchar c; len--; c = *src++; if ('\r' == c) { /* * This allows more than one CR but we must consume * some data or keep state over this otherwise. */ continue; } else if ('\n' == c) { attr->state = CHUNK_STATE_SIZE; break; } else { /* * Normally it is an error, there should be CRLF after * the chunk data. However, they might have forgotten * to send the '\n' or the whole sequence. * * If what follows looks like a valid chunk size, then * we should be able to resync properly: Unread the * character and move on to the chunk size decoding. */ if (!(attr->flags & IF_NO_CRLF)) { attr->flags |= IF_NO_CRLF; g_warning("Host %s forgot CRLF after data", gnet_host_to_string(&rx->host)); } len++; src--; attr->state = CHUNK_STATE_SIZE; break; } } break; case CHUNK_STATE_SIZE: g_assert(attr->hex_pos < sizeof attr->hex_buf); while (len > 0) { uchar c; len--; c = *src++; if (is_ascii_xdigit(c)) { if (attr->hex_pos >= sizeof attr->hex_buf) { error_str = "Overflow in chunk-size"; goto error; } /* Collect up to 16 hex characters */ attr->hex_buf[attr->hex_pos++] = c; } else { /* * There might be a chunk-extension after the * hexadecimal chunk-size but there shouldn't * anything else. */ if ( 0 == attr->hex_pos || (!is_ascii_space(c) && ';' != c) ) { error_str = "Bad chunk-size"; goto error; } attr->state = CHUNK_STATE_EXT; break; } } break; case CHUNK_STATE_EXT: /* Just skip over the chunk-extension */ while (len > 0) { len--; if ('\n' == *src++) { /* * Pick up the collected hex digits and * calculate the chunk-size. */ g_assert(attr->hex_pos > 0); g_assert(attr->hex_pos <= sizeof attr->hex_buf); { uint64 v = 0; uint i; for (i = 0; i < attr->hex_pos; i++) v = (v << 4) | hex2int_inline(attr->hex_buf[i]); attr->data_remain = v; attr->hex_pos = 0; } attr->state = 0 != attr->data_remain ? CHUNK_STATE_DATA : CHUNK_STATE_TRAILER_START; break; } } break; case CHUNK_STATE_TRAILER_START: /* We've reached another trailer line */ if (len < 1) break; if ('\r' == src[0]) { /* * This allows more than one CR but we must consume * some data or keep state over this otherwise. */ src++; len--; } if (len < 1) break; if ('\n' == src[0]) { /* An empty line means the end of all trailers was reached */ src++; len--; attr->state = CHUNK_STATE_END; break; } attr->state = CHUNK_STATE_TRAILER; /* FALL THROUGH */ case CHUNK_STATE_TRAILER: /* Just skip over the trailer line */ while (len > 0) { len--; if ('\n' == *src++) { /* * Now check whether there's another trailer * line or whether we've reached the end */ attr->state = CHUNK_STATE_TRAILER_START; break; } } break; case CHUNK_STATE_END: /* * We're not supposed to receive data after the chunk stream * has been ended. But if we do, it means either we * misinterpreted the chunk end stream or the other end is just * going berserk. */ error_str = "Remaining data after chunk end"; goto error; case CHUNK_STATE_DATA: case CHUNK_STATE_ERROR: case NUM_CHUNK_STATES: g_assert_not_reached(); break; } /* NB: Some data from ``src'' must have been consumed or an * infinite loop may occur. */ if (CHUNK_STATE_DATA == attr->state) { if (GNET_PROPERTY(rx_debug) > 9) g_debug("parse_chunk: chunk size %s bytes", uint64_to_string(attr->data_remain)); break; } } while (len > 0 && CHUNK_STATE_END != attr->state); if (p_error_str) *p_error_str = NULL; return size - len; error: if (p_error_str) *p_error_str = error_str; attr->state = CHUNK_STATE_ERROR; return 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> [", 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); }
/** * Displays assorted status information */ enum shell_reply shell_exec_status(struct gnutella_shell *sh, int argc, const char *argv[]) { const char *cur; const option_t options[] = { { "i", &cur }, }; int parsed; char buf[2048]; time_t now; shell_check(sh); g_assert(argv); g_assert(argc > 0); parsed = shell_options_parse(sh, argv, options, G_N_ELEMENTS(options)); if (parsed < 0) return REPLY_ERROR; argv += parsed; /* args[0] is first command argument */ argc -= parsed; /* counts only command arguments now */ now = tm_time(); /* Leading flags */ { char flags[47]; const char *fw; const char *fd; const char *pmp; const char *dht; /* * The flags are displayed as followed: * * UMP port mapping configured via UPnP * NMP port mapping configured via NAT-PMP * pmp port mapping available (UPnP or NAT-PMP), un-configured * CLK clock, GTKG expired * !FD or FD red or yellow bombs for fd shortage * STL upload stalls * gUL/yUL/rUL green, yellow or red upload early stalling levels * CPU cpu overloaded * MOV file moving * SHA SHA-1 rebuilding or verifying * TTH TTH rebuilding or verifying * LIB library rescan * :FW or FW indicates whether hole punching is possible * udp or UDP indicates UDP firewalling (lowercased for hole punching) * TCP indicates TCP-firewalled * - the happy face: no firewall * sDH/lDH/bDH seeded, own KUID looking or bootstrapping DHT * A or P active or passive DHT mode * UP or LF ultrapeer or leaf mode */ pmp = (GNET_PROPERTY(upnp_possible) || GNET_PROPERTY(natpmp_possible)) ? "pmp " : empty; if ( (GNET_PROPERTY(enable_upnp) || GNET_PROPERTY(enable_natpmp)) && GNET_PROPERTY(port_mapping_successful) ) { pmp = GNET_PROPERTY(enable_natpmp) ? "NMP " : "UMP "; } if (dht_enabled()) { dht = empty; switch ((enum dht_bootsteps) GNET_PROPERTY(dht_boot_status)) { case DHT_BOOT_NONE: case DHT_BOOT_SHUTDOWN: break; case DHT_BOOT_SEEDED: dht = "sDH "; break; case DHT_BOOT_OWN: dht = "lDH "; break; case DHT_BOOT_COMPLETING: dht = "bDH "; break; case DHT_BOOT_COMPLETED: dht = dht_is_active() ? "A " : "P "; break; case DHT_BOOT_MAX_VALUE: g_assert_not_reached(); } } else { dht = empty; } if (GNET_PROPERTY(is_firewalled) && GNET_PROPERTY(is_udp_firewalled)) { fw = GNET_PROPERTY(recv_solicited_udp) ? ":FW " : "FW "; } else if (GNET_PROPERTY(is_firewalled)) { fw = "TCP "; } else if (GNET_PROPERTY(is_udp_firewalled)) { fw = GNET_PROPERTY(recv_solicited_udp) ? "udp " : "UDP "; } else { fw = "- "; } if (GNET_PROPERTY(file_descriptor_runout)) { fd = "!FD "; } else if (GNET_PROPERTY(file_descriptor_shortage)) { fd = "FD "; } else { fd = empty; } gm_snprintf(flags, sizeof flags, "<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>", pmp, GNET_PROPERTY(download_queue_frozen) ? "DFZ " : empty, GNET_PROPERTY(ancient_version) ? "CLK " : empty, fd, GNET_PROPERTY(uploads_stalling) ? "STL " : empty, GNET_PROPERTY(uploads_bw_ignore_stolen) ? "gUL " : empty, GNET_PROPERTY(uploads_bw_uniform) ? "yUL " : empty, GNET_PROPERTY(uploads_bw_no_stealing) ? "rUL " : empty, GNET_PROPERTY(overloaded_cpu) ? "CPU " : empty, GNET_PROPERTY(file_moving) ? "MOV " : empty, (GNET_PROPERTY(sha1_rebuilding) || GNET_PROPERTY(sha1_verifying)) ? "SHA " : empty, (GNET_PROPERTY(tth_rebuilding) || GNET_PROPERTY(tth_verifying)) ? "TTH " : empty, GNET_PROPERTY(library_rebuilding) ? "LIB " : empty, fw, dht, settings_is_ultra() ? "UP" : "LF"); gm_snprintf(buf, sizeof buf, "+%s+\n" "| %-18s%51s |\n" "|%s|\n", dashes, "Status", flags, equals); shell_write(sh, buf); } /* General status */ { const char *blackout; short_string_t leaf_switch; short_string_t ultra_check; leaf_switch = timestamp_get_string( GNET_PROPERTY(node_last_ultra_leaf_switch)); ultra_check = timestamp_get_string( GNET_PROPERTY(node_last_ultra_check)); if (GNET_PROPERTY(is_firewalled) && GNET_PROPERTY(is_udp_firewalled)) { blackout = GNET_PROPERTY(recv_solicited_udp) ? "TCP,udp" : "TCP,UDP"; } else if (GNET_PROPERTY(is_firewalled)) { blackout = "TCP"; } else if (GNET_PROPERTY(is_udp_firewalled)) { blackout = GNET_PROPERTY(recv_solicited_udp) ? "udp" : "UDP"; } else { blackout = "None"; } gm_snprintf(buf, sizeof buf, "| Mode: %-9s Last Switch: %-19s%2s|\n" "| Uptime: %-9s Last Check: %-19s%2s|\n" "| Port: %-9u Blackout: %-7s%14s|\n" "|%s|\n", GNET_PROPERTY(online_mode) ? node_peermode_to_string(GNET_PROPERTY(current_peermode)) : "offline", GNET_PROPERTY(node_last_ultra_leaf_switch) ? leaf_switch.str : "never", space, short_time(delta_time(now, GNET_PROPERTY(start_stamp))), GNET_PROPERTY(node_last_ultra_check) ? ultra_check.str : "never", space, socket_listen_port(), blackout, space, equals); shell_write(sh, buf); } /* IPv4 info */ switch (GNET_PROPERTY(network_protocol)) { case NET_USE_BOTH: case NET_USE_IPV4: gm_snprintf(buf, sizeof buf, "| IPv4: %-44s Since: %-12s|\n", host_addr_to_string(listen_addr()), short_time(delta_time(now, GNET_PROPERTY(current_ip_stamp)))); shell_write(sh, buf); } /* IPv6 info */ switch (GNET_PROPERTY(network_protocol)) { case NET_USE_BOTH: gm_snprintf(buf, sizeof buf, "|%s|\n", dashes); shell_write(sh, buf); /* FALL THROUGH */ case NET_USE_IPV6: gm_snprintf(buf, sizeof buf, "| IPv6: %-44s Since: %-12s|\n", host_addr_to_string(listen_addr6()), short_time(delta_time(now, GNET_PROPERTY(current_ip6_stamp)))); shell_write(sh, buf); } /* Node counts */ gm_snprintf(buf, sizeof buf, "|%s|\n" "| Peers: %-7u Ultra %4u/%-7u Leaf %4u/%-6u Legacy %4u/%-4u |\n" "| Downloads %4u/%-4u Uploads %4u/%-7u Browse %4u/%-4u |\n" "|%s|\n", equals, GNET_PROPERTY(node_ultra_count) + GNET_PROPERTY(node_leaf_count) + GNET_PROPERTY(node_normal_count), GNET_PROPERTY(node_ultra_count), settings_is_ultra() ? GNET_PROPERTY(max_connections) : GNET_PROPERTY(max_ultrapeers), GNET_PROPERTY(node_leaf_count), GNET_PROPERTY(max_leaves), GNET_PROPERTY(node_normal_count), GNET_PROPERTY(normal_connections), GNET_PROPERTY(dl_active_count), GNET_PROPERTY(dl_running_count), GNET_PROPERTY(ul_running), GNET_PROPERTY(ul_registered), GNET_PROPERTY(html_browse_served) + GNET_PROPERTY(qhits_browse_served), GNET_PROPERTY(html_browse_count) + GNET_PROPERTY(qhits_browse_count), equals); shell_write(sh, buf); /* Bandwidths */ { const bool metric = GNET_PROPERTY(display_metric_units); short_string_t gnet_in, http_in, leaf_in, gnet_out, http_out, leaf_out; short_string_t dht_in, dht_out; gnet_bw_stats_t bw_stats, bw2_stats; const char *bwtype = cur ? "(cur)" : "(avg)"; gnet_get_bw_stats(BW_GNET_IN, &bw_stats); gnet_get_bw_stats(BW_GNET_UDP_IN, &bw2_stats); gnet_in = short_rate_get_string( cur ? bw_stats.current + bw2_stats.current : bw_stats.average + bw2_stats.average, metric); gnet_get_bw_stats(BW_GNET_OUT, &bw_stats); gnet_get_bw_stats(BW_GNET_UDP_OUT, &bw2_stats); gnet_out = short_rate_get_string( cur ? bw_stats.current + bw2_stats.current : bw_stats.average + bw2_stats.average, metric); gnet_get_bw_stats(BW_HTTP_IN, &bw_stats); http_in = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gnet_get_bw_stats(BW_HTTP_OUT, &bw_stats); http_out = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gnet_get_bw_stats(BW_LEAF_IN, &bw_stats); leaf_in = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gnet_get_bw_stats(BW_LEAF_OUT, &bw_stats); leaf_out = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gnet_get_bw_stats(BW_DHT_IN, &bw_stats); dht_in = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gnet_get_bw_stats(BW_DHT_OUT, &bw_stats); dht_out = short_rate_get_string( cur ? bw_stats.current : bw_stats.average, metric); gm_snprintf(buf, sizeof buf, "| %-70s|\n" "|%71s|\n" "| %5s In: %13s %13s %13s %13s |\n" "| %5s Out: %13s %13s %13s %13s |\n", "Bandwidth:" " Gnutella Leaf HTTP DHT", dashes, bwtype, gnet_in.str, leaf_in.str, http_in.str, dht_in.str, bwtype, gnet_out.str, leaf_out.str, http_out.str, dht_out.str); shell_write(sh, buf); } { char line[128]; bool metric = GNET_PROPERTY(display_metric_units); gm_snprintf(buf, sizeof buf, "|%s|\n", equals); shell_write(sh, buf); concat_strings(line, sizeof line, "Shares ", uint64_to_string(shared_files_scanned()), " file", shared_files_scanned() == 1 ? "" : "s", " ", short_kb_size(shared_kbytes_scanned(), metric), " total", (void *) 0); gm_snprintf(buf, sizeof buf, "| %-35s Up: %-11s Down: %-11s |\n", line, short_byte_size(GNET_PROPERTY(ul_byte_count), metric), short_byte_size2(GNET_PROPERTY(dl_byte_count), metric)); shell_write(sh, buf); gm_snprintf(buf, sizeof buf, "+%s+\n", dashes); shell_write(sh, buf); } return REPLY_READY; }
GenRet VarSymbol::codegenVarSymbol(bool lhsInSetReference) { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; ret.chplType = typeInfo(); if( outfile ) { // dtString immediates don't actually codegen as immediates, we just use // them for param string functionality. if (immediate && ret.chplType != dtString) { ret.isLVPtr = GEN_VAL; if (immediate->const_kind == CONST_KIND_STRING) { ret.c += '"'; ret.c += immediate->v_string; ret.c += '"'; } else if (immediate->const_kind == NUM_KIND_BOOL) { std::string bstring = (immediate->bool_value())?"true":"false"; const char* castString = "("; switch (immediate->num_index) { case BOOL_SIZE_1: case BOOL_SIZE_SYS: case BOOL_SIZE_8: castString = "UINT8("; break; case BOOL_SIZE_16: castString = "UINT16("; break; case BOOL_SIZE_32: castString = "UINT32("; break; case BOOL_SIZE_64: castString = "UINT64("; break; default: INT_FATAL("Unexpected immediate->num_index: %d\n", immediate->num_index); } ret.c = castString + bstring + ")"; } else if (immediate->const_kind == NUM_KIND_INT) { int64_t iconst = immediate->int_value(); if (iconst == (1ll<<63)) { ret.c = "-INT64(9223372036854775807) - INT64(1)"; } else if (iconst <= -2147483648ll || iconst >= 2147483647ll) { ret.c = "INT64(" + int64_to_string(iconst) + ")"; } else { const char* castString = "("; switch (immediate->num_index) { case INT_SIZE_8: castString = "INT8("; break; case INT_SIZE_16: castString = "INT16("; break; case INT_SIZE_32: castString = "INT32("; break; case INT_SIZE_64: castString = "INT64("; break; default: INT_FATAL("Unexpected immediate->num_index: %d\n", immediate->num_index); } ret.c = castString + int64_to_string(iconst) + ")"; } } else if (immediate->const_kind == NUM_KIND_UINT) { uint64_t uconst = immediate->uint_value(); if( uconst <= (uint64_t) INT32_MAX ) { const char* castString = "("; switch (immediate->num_index) { case INT_SIZE_8: castString = "UINT8("; break; case INT_SIZE_16: castString = "UINT16("; break; case INT_SIZE_32: castString = "UINT32("; break; case INT_SIZE_64: castString = "UINT64("; break; default: INT_FATAL("Unexpected immediate->num_index: %d\n", immediate->num_index); } ret.c = castString + uint64_to_string(uconst) + ")"; } else { ret.c = "UINT64(" + uint64_to_string(uconst) + ")"; } } else { ret.c = cname; // in C, all floating point literals are (double) } } else { // not immediate // is it a constant extern? If it is, it might be for example // an enum or #define'd value, in which case taking the address // of it is simply nonsense. Therefore, we code generate // extern const symbols as GEN_VAL (ie not an lvalue). if( hasFlag(FLAG_CONST) && hasFlag(FLAG_EXTERN) ) { ret.isLVPtr = GEN_VAL; ret.c = cname; } else { QualifiedType qt = qualType(); if (lhsInSetReference) { ret.c = '&'; ret.c += cname; ret.isLVPtr = GEN_PTR; if (qt.isRef() && !qt.isRefType()) ret.chplType = getOrMakeRefTypeDuringCodegen(typeInfo()); else if (qt.isWideRef() && !qt.isWideRefType()) { Type* refType = getOrMakeRefTypeDuringCodegen(typeInfo()); ret.chplType = getOrMakeWideTypeDuringCodegen(refType); } } else { if (qt.isRef() && !qt.isRefType()) { ret.c = cname; ret.isLVPtr = GEN_PTR; } else if(qt.isWideRef() && !qt.isWideRefType()) { ret.c = cname; ret.isLVPtr = GEN_WIDE_PTR; } else { ret.c = '&'; ret.c += cname; ret.isLVPtr = GEN_PTR; } } } // Print string contents in a comment if developer mode // and savec is set. if (developer && 0 != strcmp(saveCDir, "") && immediate && ret.chplType == dtString && immediate->const_kind == CONST_KIND_STRING) { if (strstr(immediate->v_string, "/*") || strstr(immediate->v_string, "*/")) { // Don't emit comment b/c string contained comment character. } else { ret.c += " /* \""; ret.c += immediate->v_string; ret.c += "\" */"; } } } return ret; } else { #ifdef HAVE_LLVM // for LLVM // Handle extern type variables. if( hasFlag(FLAG_EXTERN) && isType() ) { // code generate the type. GenRet got = typeInfo(); return got; } // for nil, generate a void pointer of chplType dtNil // to allow LLVM pointer cast // e.g. T = ( (locale) (nil) ); // // We would just compare against dtNil, but in some cases // the code generator needs to assign e.g. // _ret:dtNil = nil if( typeInfo() == dtNil && 0 == strcmp(cname, "nil") ) { GenRet voidPtr; voidPtr.val = llvm::Constant::getNullValue(info->builder->getInt8PtrTy()); voidPtr.chplType = dtNil; return voidPtr; } if (typeInfo() == dtBool){ // since "true" and "false" are read into the LVT during ReadMacrosAction // they will generate an LLVM value of type i32 instead of i8 if (0 == strcmp(cname, "false")){ GenRet boolVal = new_UIntSymbol(0, INT_SIZE_8)->codegen(); return boolVal; } if (0 == strcmp(cname, "true")){ GenRet boolVal = new_UIntSymbol(1, INT_SIZE_8)->codegen(); return boolVal; } } if(!isImmediate()) { // check LVT for value GenRet got = info->lvt->getValue(cname); got.chplType = typeInfo(); if( got.val ) { return got; } } if(isImmediate()) { ret.isLVPtr = GEN_VAL; if(immediate->const_kind == CONST_KIND_STRING) { if(llvm::Value *value = info->module->getNamedGlobal(name)) { ret.val = value; ret.isLVPtr = GEN_PTR; return ret; } llvm::Value *constString = codegenImmediateLLVM(immediate); llvm::GlobalVariable *globalValue = llvm::cast<llvm::GlobalVariable>( info->module->getOrInsertGlobal (name, info->builder->getInt8PtrTy())); globalValue->setConstant(true); globalValue->setInitializer(llvm::cast<llvm::Constant>( info->builder->CreateConstInBoundsGEP2_32( #if HAVE_LLVM_VER >= 37 NULL, #endif constString, 0, 0))); ret.val = globalValue; ret.isLVPtr = GEN_PTR; } else { ret.val = codegenImmediateLLVM(immediate); } return ret; } if(std::string(cname) == "0") { // Chapel compiler should not make these. INT_FATAL(" zero value BOO "); return ret; } else if (std::string(cname) == "NULL") { GenRet voidPtr; voidPtr.val = llvm::Constant::getNullValue(info->builder->getInt8PtrTy()); voidPtr.chplType = typeInfo(); return voidPtr; } #endif } INT_FATAL("Could not code generate %s - " "perhaps it is a complex macro?", cname); return ret; }
static void print_hsep_table(struct gnutella_shell *sh, hsep_triple *table, int triples, hsep_triple *non_hsep_ptr) { static hsep_triple empty_non_hsep; const char *hops_str = _("Hops"); const char *nodes_str = _("Nodes"); const char *files_str = _("Files"); const char *size_str = _("Size"); hsep_triple non_hsep, *t; char buf[200]; size_t maxlen[4]; size_t i; if (!non_hsep_ptr) { non_hsep_ptr = &empty_non_hsep; } memcpy(non_hsep, non_hsep_ptr, sizeof non_hsep); t = &table[1]; /* * Determine maximum width of each column. */ maxlen[0] = strlen(hops_str); /* length of Hops */ maxlen[1] = strlen(nodes_str); /* length of Nodes */ maxlen[2] = strlen(files_str); /* length of Files */ maxlen[3] = strlen(size_str); /* length of Size */ for (i = 0; i < UNSIGNED(triples) * 4; i++) { size_t n; unsigned m = i % 4; switch (m) { case 0: n = strlen(uint64_to_string(i / 4 + 1)); break; case 1: case 2: case 3: { unsigned j = 0; switch (m) { case 1: j = HSEP_IDX_NODES; break; case 2: j = HSEP_IDX_FILES; break; case 3: j = HSEP_IDX_KIB; break; } n = strlen(uint64_to_string(t[i][j] + non_hsep[j])); } break; default: n = 0; g_assert_not_reached(); } if (n > maxlen[m]) maxlen[m] = n; } str_bprintf(buf, sizeof buf, "%*s %*s %*s %*s\n", (int) maxlen[0], hops_str, (int) maxlen[1], nodes_str, (int) maxlen[2], files_str, (int) maxlen[3], size_str); shell_write(sh, buf); for (i = maxlen[0] + maxlen[1] + maxlen[2] + maxlen[3] + 6; i > 0; i--) shell_write(sh, "-"); shell_write(sh, "\n"); t = &table[1]; for (i = 0; i < UNSIGNED(triples); i++) { const char *s1, *s2, *s3; s1 = uint64_to_string(t[i][HSEP_IDX_NODES] + non_hsep[HSEP_IDX_NODES]); s2 = uint64_to_string2(t[i][HSEP_IDX_FILES] + non_hsep[HSEP_IDX_FILES]); s3 = short_kb_size(t[i][HSEP_IDX_KIB] + non_hsep[HSEP_IDX_KIB], GNET_PROPERTY(display_metric_units)); str_bprintf(buf, sizeof buf, "%*u %*s %*s %*s\n", (int) maxlen[0], (unsigned) (i + 1), (int) maxlen[1], s1, (int) maxlen[2], s2, (int) maxlen[3], s3); shell_write(sh, buf); } }
static enum shell_reply shell_exec_download_show(struct gnutella_shell *sh, int argc, const char *argv[]) { fileinfo_t *fi; struct guid guid; const char *id, *property; gnet_fi_status_t status; gnet_fi_info_t *info; int i; shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc < 3) { shell_set_msg(sh, "parameter missing"); goto error; } id = argv[2]; if (!hex_to_guid(id, &guid)) { shell_set_msg(sh, "Unparsable ID"); goto error; } fi = file_info_by_guid(&guid); if (NULL == fi) { shell_set_msg(sh, "Invalid ID"); goto error; } info = guc_fi_get_info(fi->fi_handle); guc_fi_get_status(fi->fi_handle, &status); for (i = 3; i < argc; i++) { property = argv[i]; if (0 == strcmp(property, "id")) { show_property(sh, property, guid_to_string(info->guid)); } else if (0 == strcmp(property, "filename")) { show_property(sh, property, info->filename); } else if (0 == strcmp(property, "pathname")) { show_property(sh, property, fi->pathname); } else if (0 == strcmp(property, "size")) { show_property(sh, property, filesize_to_string(info->size)); } else if (0 == strcmp(property, "sha1")) { show_property(sh, property, info->sha1 ? sha1_to_urn_string(info->sha1) : ""); } else if (0 == strcmp(property, "tth")) { show_property(sh, property, info->tth ? tth_to_urn_string(info->tth) : ""); } else if (0 == strcmp(property, "bitprint")) { show_property(sh, property, (info->sha1 && info->tth) ? bitprint_to_urn_string(info->sha1, info->tth) : ""); } else if (0 == strcmp(property, "created")) { show_property(sh, property, info->created ? timestamp_to_string(info->created) : ""); } else if (0 == strcmp(property, "modified")) { show_property(sh, property, status.modified ? timestamp_to_string(status.modified) : ""); } else if (0 == strcmp(property, "downloaded")) { show_property(sh, property, filesize_to_string(status.done)); } else if (0 == strcmp(property, "uploaded")) { show_property(sh, property, uint64_to_string(status.uploaded)); } else if (0 == strcmp(property, "paused")) { show_property(sh, property, boolean_to_string(status.paused)); } else if (0 == strcmp(property, "seeding")) { show_property(sh, property, boolean_to_string(status.seeding)); } else if (0 == strcmp(property, "verifying")) { show_property(sh, property, boolean_to_string(status.verifying)); } else if (0 == strcmp(property, "finished")) { show_property(sh, property, boolean_to_string(status.finished)); } else if (0 == strcmp(property, "complete")) { show_property(sh, property, boolean_to_string(status.complete)); } else if (0 == strcmp(property, "magnet")) { char *magnet = file_info_build_magnet(fi->fi_handle); show_property(sh, property, EMPTY_STRING(magnet)); HFREE_NULL(magnet); } } guc_fi_free_info(info); return REPLY_READY; error: return REPLY_ERROR; }