#include #include #include #include #include #include #include #include #include #include #include #include #include "list.h" #include "gnet.h" #include "gnetfs.h" #include "search.h" #include "xfer.h" static void stop_xfer(struct gnet_locator *loc){ gnet_xfer_shutdown(loc); list_del(&loc->list); free(loc->name); free(loc); } struct gnet_locator* find_xfer(struct local_ctx *ctx, char *txt){ struct list_head *p; TRACE("searching xfer(%s)", txt); list_for_each(p, &ctx->opened_files) if(!(strcmp(txt, list_entry(p, struct gnet_locator, list)->name))){ TRACE("xfer found"); return list_entry(p, struct gnet_locator, list); } TRACE("xfer not found"); return NULL; } struct gnet_locator* create_xfer(struct local_ctx *ctx, char *txt){ struct global_ctx *glob = *ctx->global; struct gnet_locator *xfer; struct search *srch; struct result *res; struct gnet_locator *loc; char *sep; TRACE("creating xfer(%s)", txt); if(!(sep = strrchr(txt, '/'))){ WARN("no '/' separator found!"); return NULL; } if((xfer = find_xfer(ctx, sep + 1))){ TRACE("xfer already created"); return xfer; } *sep = 0; pthread_mutex_lock(&glob->lock); if(!(srch = find_search_by_txt(glob, txt))) goto fail_lock; if(!(res = find_result_by_name(srch, sep + 1))) goto fail_lock; if(list_empty(&res->locators)){ TRACE("no available locators"); goto fail_lock; } loc = list_entry(res->locators.next, struct gnet_locator, list); list_del(&loc->list); list_add_tail(&loc->list, &res->locators); *sep = '/'; if(!(xfer = malloc(sizeof(struct gnet_locator)))) goto fail_lock; memcpy(xfer, loc, sizeof(struct gnet_locator)); if(!(xfer->name = malloc(strlen(sep + 1) + 1))) goto fail_xfer; strcpy(xfer->name, sep + 1); xfer->xfer = NULL; pthread_mutex_unlock(&glob->lock); list_add(&xfer->list, &ctx->opened_files); TRACE("xfer created"); return xfer; fail_xfer: free(xfer); fail_lock: pthread_mutex_unlock(&glob->lock); return NULL; } int xfer_read(struct local_ctx *ctx, char *txt, unsigned int offset, unsigned int count, char *buf){ struct gnet_locator *xfer; TRACE("txt: %s", txt); if(!(xfer = create_xfer(ctx, txt))){ WARN("could not create xfer"); return -1; } TRACE("reading %d bytes", count); return gnet_xfer_read((*ctx->global)->gnet, xfer, offset, count, buf); }