/** * Handles the download command. */ enum shell_reply shell_exec_download(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc < 2) goto error; #define CMD(name) G_STMT_START { \ if (0 == ascii_strcasecmp(argv[1], #name)) \ return shell_exec_download_ ## name(sh, argc, argv); \ } G_STMT_END CMD(abort); CMD(add); CMD(list); CMD(pause); CMD(resume); CMD(rename); CMD(show); #undef CMD shell_set_msg(sh, _("Unknown operation")); goto error; error: return REPLY_ERROR; }
static enum shell_reply shell_exec_download_resume(struct gnutella_shell *sh, int argc, const char *argv[]) { fileinfo_t *fi; struct guid guid; const char *id; 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; } file_info_resume(fi); return REPLY_READY; error: return REPLY_ERROR; }
static enum shell_reply shell_exec_lib_show_callout(struct gnutella_shell *sh, int argc, const char *argv[]) { pslist_t *info, *sl; str_t *s; size_t maxlen = 0; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_write(sh, "100~\n"); shell_write(sh, "T Events Per. Idle Last Period Heartbeat Triggered Name (Parent)" "\n"); info = cq_info_list(); s = str_new(80); PSLIST_FOREACH(info, sl) { cq_info_t *cqi = sl->data; size_t len; cq_info_check(cqi); len = vstrlen(cqi->name); maxlen = MAX(len, maxlen); }
enum shell_reply shell_exec_set(struct gnutella_shell *sh, int argc, const char *argv[]) { const char *verbose; const option_t options[] = { { "v", &verbose }, }; property_t prop; int parsed; 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 */ if (argc < 1) { shell_set_msg(sh, _("Property missing")); goto error; } prop = gnet_prop_get_by_name(argv[0]); if (prop == NO_PROP) { shell_set_msg(sh, _("Unknown property")); goto error; } if (argc < 2) { shell_set_msg(sh, _("Value missing")); goto error; } if (gnet_prop_is_internal(prop)) { shell_set_msg(sh, _("Property cannot be changed")); goto error; } if (verbose) { shell_write_linef(sh, REPLY_READY, _("Previous value was %s"), shell_property_to_string(prop)); } gnet_prop_set_from_string(prop, argv[1]); if (verbose) { shell_write_linef(sh, REPLY_READY, _("New value is %s"), shell_property_to_string(prop)); } shell_set_msg(sh, _("Value found and set")); return REPLY_READY; error: return REPLY_ERROR; }
enum shell_reply shell_exec_print(struct gnutella_shell *sh, int argc, const char *argv[]) { property_t prop; shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc < 2) { shell_set_msg(sh, _("Property missing")); goto error; } prop = gnet_prop_get_by_name(argv[1]); if (prop == NO_PROP) { char buf[120]; str_bprintf(buf, sizeof buf, _("Unknown property \"%s\""), argv[1]); shell_set_msg(sh, buf); goto error; } shell_write(sh, _("Value: ")); shell_write(sh, gnet_prop_to_typed_string(prop)); shell_write(sh, "\n"); shell_set_msg(sh, _("Value found and displayed")); return REPLY_READY; error: return REPLY_ERROR; }
enum shell_reply shell_exec_quit(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, _("Good bye")); shell_exit(sh); return REPLY_BYE; }
static enum shell_reply shell_exec_download_list(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); file_info_foreach(print_download_id, sh); return REPLY_READY; }
static void show_property(struct gnutella_shell *sh, const char *name, const char *value) { shell_check(sh); g_return_if_fail(name); g_return_if_fail(value); shell_write(sh, name); shell_write(sh, "="); shell_write(sh, value); shell_write(sh, "\n"); }
static void print_download_id(gnet_fi_t handle, void *udata) { struct gnutella_shell *sh = udata; gnet_fi_info_t *info; shell_check(sh); info = guc_fi_get_info(handle); g_return_if_fail(info); shell_write(sh, guid_to_string(info->guid)); shell_write(sh, "\n"); /* Terminate line */ }
enum shell_reply shell_exec_help(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_write(sh, "100~\n"); if (argc > 1) { shell_write(sh, shell_cmd_get_help(argc - 1, &argv[1])); } else { size_t i; shell_write(sh, "Use \"help <cmd>\" for additional help about a command.\n"); shell_write(sh, "The following commands are available:\n"); for (i = 0; i < G_N_ELEMENTS(commands); i++) { const char *name = commands[i].name; if (NULL == name || '\0' == name[0]) continue; shell_write(sh, name); { size_t len = strlen(name); char pad[10]; if (len < sizeof pad) { memset(pad, ' ', sizeof pad); pad[sizeof pad - len] = '\0'; shell_write(sh, pad); } } { const char *summary = shell_cmd_get_summary(name); if (summary) { shell_write(sh, " - "); shell_write(sh, summary); } } shell_write(sh, "\n"); } } shell_write(sh, ".\n"); return REPLY_READY; }
static void print_download_info(gnet_fi_t handle, void *udata) { struct gnutella_shell *sh = udata; gnet_fi_status_t status; gnet_fi_info_t *info; char buf[1024]; shell_check(sh); info = guc_fi_get_info(handle); g_return_if_fail(info); guc_fi_get_status(handle, &status); str_bprintf(ARYLEN(buf), "ID: %s", guid_to_string(info->guid)); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ str_bprintf(ARYLEN(buf), "Filename: \"%s\"", info->filename); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ str_bprintf(ARYLEN(buf), "Hash: %s", info->sha1 ? sha1_to_urn_string(info->sha1) : "<none>"); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ str_bprintf(ARYLEN(buf), "Status: %s", file_info_status_to_string(&status)); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ str_bprintf(ARYLEN(buf), "Size: %s", compact_size(status.size, GNET_PROPERTY(display_metric_units))); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ str_bprintf(ARYLEN(buf), "Done: %u%% (%s)", filesize_per_100(status.size, status.done), compact_size(status.done, GNET_PROPERTY(display_metric_units))); shell_write(sh, buf); shell_write(sh, "\n"); /* Terminate line */ shell_write(sh, "--\n"); guc_fi_free_info(info); }
/** * Displays all active downloads. */ enum shell_reply shell_exec_downloads(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n"); file_info_foreach(print_download_info, sh); shell_write(sh, ".\n"); /* Terminate message body */ return REPLY_READY; }
/** * Displays all active uploads */ enum shell_reply shell_exec_uploads(struct gnutella_shell *sh, int argc, const char *argv[]) { const pslist_t *sl; pslist_t *sl_info; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n"); sl_info = upload_get_info_list(); PSLIST_FOREACH(sl_info, sl) { print_upload_info(sh, sl->data); }
static enum shell_reply shell_exec_download_rename(struct gnutella_shell *sh, int argc, const char *argv[]) { fileinfo_t *fi; struct guid guid; const char *id, *filename; shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc != 4) { shell_set_msg(sh, "Invalid parameter count"); goto error; } id = argv[2]; filename = argv[3]; 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; } if (!file_info_rename(fi, filename)) { shell_set_msg(sh, "Renaming failed"); goto error; } return REPLY_READY; error: return REPLY_ERROR; }
static enum shell_reply shell_exec_download_add(struct gnutella_shell *sh, int argc, const char *argv[]) { const char *url; gboolean success; shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc < 3) { shell_set_msg(sh, _("URL missing")); goto error; } url = argv[2]; if (is_strcaseprefix(url, "http://")) { success = download_handle_http(url); } else if (is_strcaseprefix(url, "magnet:?")) { unsigned n_downloads, n_searches; n_downloads = download_handle_magnet(url); n_searches = search_handle_magnet(url); success = n_downloads > 0 || n_searches > 0; } else { success = FALSE; } if (!success) { shell_set_msg(sh, _("The download could not be created")); goto error; } shell_set_msg(sh, _("Download added")); return REPLY_READY; error: return REPLY_ERROR; }
/** * Displays all connected nodes */ enum shell_reply shell_exec_nodes(struct gnutella_shell *sh, int argc, const char *argv[]) { const GSList *sl; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n" "Node Port Flags CC Since Uptime User-Agent\n"); for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) { const struct gnutella_node *n = sl->data; print_node_info(sh, n); } shell_write(sh, ".\n"); /* Terminate message body */ return REPLY_READY; }
/** * Displays all connected nodes */ enum shell_reply shell_exec_nodes(struct gnutella_shell *sh, int argc, const char *argv[]) { const pslist_t *sl; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n" "Node Flags CC Since Uptime User-Agent\n"); PSLIST_FOREACH(node_all_nodes(), sl) { const gnutella_node_t *n = sl->data; print_node_info(sh, n); } shell_write(sh, ".\n"); /* Terminate message body */ return REPLY_READY; }
/** * The "INTR" command. */ enum shell_reply shell_exec_intr(struct gnutella_shell *sh, int argc, const char *argv[]) { shell_check(sh); g_assert(argv); g_assert(argc > 0); if (shell_toggle_interactive(sh)) { /* * Special case: If INTR is the first command, we already sent a * welcome message. */ if (1 == shell_line_count(sh)) return REPLY_NONE; shell_set_msg(sh, _("Interactive mode turned on.")); } else { /* Always give them feedback on that command! */ shell_write(sh, "100 "); shell_write(sh, _("Interactive mode turned off.")); shell_write(sh, "\n"); } return REPLY_READY; }
/** * 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; }
/** * Displays horizon size information. */ enum shell_reply shell_exec_horizon(struct gnutella_shell *sh, int argc, const char *argv[]) { const char *all; const option_t options[] = { { "a", &all }, }; char buf[200]; hsep_triple globaltable[HSEP_N_MAX + 1]; hsep_triple non_hsep[1]; int parsed; unsigned num_hsep, num_total; 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; shell_write(sh, "100~\n"); hsep_get_global_table(globaltable, G_N_ELEMENTS(globaltable)); hsep_get_non_hsep_triple(non_hsep); num_hsep = globaltable[1][HSEP_IDX_NODES]; num_total = globaltable[1][HSEP_IDX_NODES] + non_hsep[0][HSEP_IDX_NODES]; str_bprintf(buf, sizeof buf, _("Total horizon size (%u/%u nodes support HSEP):"), num_hsep, num_total); shell_write(sh, buf); shell_write(sh, "\n\n"); print_hsep_table(sh, globaltable, HSEP_N_MAX, non_hsep); if (all) { const pslist_t *sl; hsep_triple table[HSEP_N_MAX + 1]; PSLIST_FOREACH(node_all_gnet_nodes(), sl) { const gnutella_node_t *n = sl->data; if ((!NODE_IS_ESTABLISHED(n)) || !(n->attrs & NODE_A_CAN_HSEP)) continue; shell_write(sh, "\n"); str_bprintf(buf, sizeof buf, _("Horizon size via HSEP node %s (%s):"), node_addr(n), node_peermode_to_string(n->peermode)); shell_write(sh, buf); shell_write(sh, "\n\n"); hsep_get_connection_table(n, table, G_N_ELEMENTS(table)); print_hsep_table(sh, table, NODE_IS_LEAF(n) ? 1 : HSEP_N_MAX, NULL); } } shell_write(sh, ".\n"); return REPLY_READY; }
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; }