/** * Enqueue /QH2 built as a message. * Callback for g2_build_qh2_results(). */ static void browse_host_record_qh2(pmsg_t *mb, void *udata) { struct browse_host_upload *bh = udata; bh->hits = pslist_prepend(bh->hits, mb); }
/** * Enqueue query hit built by creating a message. * Callback for qhit_build_results(). */ static void browse_host_record_hit(void *data, size_t len, void *udata) { struct browse_host_upload *bh = udata; bh->hits = pslist_prepend(bh->hits, gmsg_to_pmsg(data, len)); }
/** * ftw_foreach() callback to remove empty directories. */ static ftw_status_t tth_cache_cleanup_rmdir( const ftw_info_t *info, const filestat_t *unused_sb, void *data) { pslist_t **dirsp = data; (void) unused_sb; if (FTW_F_DIR & info->flags) { if (FTW_F_NOREAD & info->flags) { tth_cache_dir_rmdir(info->fpath); /* Try, we can't read it */ } else if (FTW_F_DONE & info->flags) { void *cnt = (*dirsp)->data; if (NULL == cnt && 0 != info->level) tth_cache_dir_rmdir(info->fpath); *dirsp = pslist_delete_link(*dirsp, *dirsp); /* Strip head */ } else { *dirsp = pslist_prepend(*dirsp, NULL); } return FTW_STATUS_OK; } (*dirsp)->data = int_to_pointer(1); /* There is something in directory */ return FTW_STATUS_OK; }
/** * 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 query hit 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_qhits(struct special_upload *ctx, void *const dest, size_t size) { struct browse_host_upload *bh = cast_to_browse_host_upload(ctx); size_t remain = size; char *p = dest; /* * If we have no hit pending that we can send, build some more. */ if (NULL == bh->hits) { pslist_t *files = NULL, *sl; int i; for (i = 0; i < BH_SCAN_AHEAD; i++) { shared_file_t *sf; do { /* Skip holes in indices */ bh->file_index++; sf = shared_file_sorted(bh->file_index); } while (NULL == sf && bh->file_index <= shared_files_scanned()); if (SHARE_REBUILDING == sf || NULL == sf) break; files = pslist_prepend(files, sf); } if (NULL == files) /* Did not find any more file to include */ return 0; /* We're done */ /* * Now build the query hits containing the files we selected. */ files = pslist_reverse(files); /* Preserve order */ if (bh->flags & BH_F_G2) { g2_build_qh2_results(files, i, BH_MAX_QH2_SIZE, browse_host_record_qh2, bh, &blank_guid, 0); } else { qhit_build_results(files, i, BH_MAX_QHIT_SIZE, browse_host_record_hit, bh, &blank_guid, 0, &zero_array); } g_assert(bh->hits != NULL); /* At least 1 hit enqueued */ bh->hits = pslist_reverse(bh->hits); /* Preserve order */ PSLIST_FOREACH(files, sl) { shared_file_t *sf = sl->data; shared_file_unref(&sf); }
static pslist_t * resolve_hostname(const char *host, enum net_type net) #ifdef HAS_GETADDRINFO { static const struct addrinfo zero_hints; struct addrinfo hints, *ai, *ai0 = NULL; hset_t *hs; pslist_t *sl_addr; int error; g_assert(host); hints = zero_hints; hints.ai_family = net_type_to_pf(net); error = getaddrinfo(host, NULL, &hints, &ai0); if (error) { g_message("getaddrinfo() failed for \"%s\": %s", host, gai_strerror(error)); return NULL; } sl_addr = NULL; hs = hset_create_any(host_addr_hash_func, NULL, host_addr_eq_func); for (ai = ai0; ai; ai = ai->ai_next) { host_addr_t addr; if (!ai->ai_addr) continue; addr = addrinfo_to_addr(ai); if (is_host_addr(addr) && !hset_contains(hs, &addr)) { host_addr_t *addr_copy; addr_copy = WCOPY(&addr); sl_addr = pslist_prepend(sl_addr, addr_copy); hset_insert(hs, addr_copy); } } hset_free_null(&hs); if (ai0) freeaddrinfo(ai0); return pslist_reverse(sl_addr); }
/** * Dispose of the driver resources, asynchronously. * It must be called on the top layer only. */ void tx_free(txdrv_t *tx) { tx_check(tx); g_assert(tx->upper == NULL); /* * Since we're delaying the free, we must disable servicing immediately * and prevent the stack from accepting any more data. */ tx_eager_mode(tx, FALSE); if (!(tx->flags & TX_DOWN)) tx_shutdown(tx); tx_freed = pslist_prepend(tx_freed, tx); }
/** * Add (address-resolved) item to the whitelist. */ static void whitelist_add(struct whitelist *item) { g_assert(item != NULL); g_assert(is_host_addr(item->addr)); /* * If TLS-usage was configured, re-add to the TLS cache so that * connections to that host will use TLS. */ if (item->use_tls && item->port != 0) tls_cache_insert(item->addr, item->port); if (GNET_PROPERTY(whitelist_debug)) log_whitelist_item(item, "adding"); sl_whitelist = pslist_prepend(sl_whitelist, item); }
void on_button_config_remove_dir_clicked(GtkButton *unused_button, gpointer unused_udata) { GtkTreeView *tv; GtkTreeModel *model; GtkTreeIter iter; GtkTreeSelection *selection; pslist_t *sl, *pl_dirs = NULL; char *dirs; (void) unused_button; (void) unused_udata; tv = GTK_TREE_VIEW(gui_dlg_prefs_lookup("treeview_shared_dirs")); model = gtk_tree_view_get_model(tv); if (!gtk_tree_model_get_iter_first(model, &iter)) return; /* Regenerate the string property holding a list of paths */ selection = gtk_tree_view_get_selection(tv); do { char *pathname = NULL; /* Skip items selected for removal */ if (gtk_tree_selection_iter_is_selected(selection, &iter)) continue; gtk_tree_model_get(model, &iter, 0, &pathname, (-1)); pl_dirs = pslist_prepend(pl_dirs, pathname); } while (gtk_tree_model_iter_next(model, &iter)); dirs = dirlist_to_string(pl_dirs); gnet_prop_set_string(PROP_SHARED_DIRS_PATHS, dirs); HFREE_NULL(dirs); PSLIST_FOREACH(pl_dirs, sl) { G_FREE_NULL(sl->data); }