http://prdownloads.sourceforge.net/lufs/lufs-0.9.6.tar.gz?download
[lufs.git] / filesystems / gnetfs / xfer.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <time.h>
6 #include <pthread.h>
7 #include <fcntl.h>
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11
12 #include <netinet/in.h>
13
14 #include <lufs/proto.h>
15 #include <lufs/fs.h>
16
17 #include "list.h"
18 #include "gnet.h"
19 #include "gnetfs.h"
20 #include "search.h"
21 #include "xfer.h"
22
23 static void
24 stop_xfer(struct gnet_locator *loc){
25     gnet_xfer_shutdown(loc);
26
27     list_del(&loc->list);
28
29     free(loc->name);
30     free(loc);
31 }
32
33 struct gnet_locator*
34 find_xfer(struct local_ctx *ctx, char *txt){
35     struct list_head *p;
36
37     TRACE("searching xfer(%s)", txt);
38     
39     list_for_each(p, &ctx->opened_files)
40         if(!(strcmp(txt, list_entry(p, struct gnet_locator, list)->name))){
41             TRACE("xfer found");
42             return list_entry(p, struct gnet_locator, list);
43         }
44
45     TRACE("xfer not found");
46
47     return NULL;
48 }
49
50 struct gnet_locator*
51 create_xfer(struct local_ctx *ctx, char *txt){
52     struct global_ctx *glob = *ctx->global;
53     struct gnet_locator *xfer;
54     struct search *srch;
55     struct result *res;
56     struct gnet_locator *loc;
57     char *sep;
58
59     TRACE("creating xfer(%s)", txt);
60     
61     if(!(sep = strrchr(txt, '/'))){
62         WARN("no '/' separator found!");
63         return NULL;
64     }
65
66     if((xfer = find_xfer(ctx, sep + 1))){
67         TRACE("xfer already created");
68         return xfer;
69     }
70
71     *sep = 0;
72
73     pthread_mutex_lock(&glob->lock);
74
75     if(!(srch = find_search_by_txt(glob, txt)))
76         goto fail_lock;
77
78
79     if(!(res = find_result_by_name(srch, sep + 1)))
80         goto fail_lock;
81
82     if(list_empty(&res->locators)){
83         TRACE("no available locators");
84         goto fail_lock;
85     }
86
87     loc = list_entry(res->locators.next, struct gnet_locator, list);
88
89     list_del(&loc->list);
90     list_add_tail(&loc->list, &res->locators);
91
92     *sep = '/';
93
94     if(!(xfer = malloc(sizeof(struct gnet_locator))))
95         goto fail_lock;
96
97     memcpy(xfer, loc, sizeof(struct gnet_locator));
98
99     if(!(xfer->name = malloc(strlen(sep + 1) + 1)))
100         goto fail_xfer;
101
102     strcpy(xfer->name, sep + 1);
103     xfer->xfer = NULL;
104
105     pthread_mutex_unlock(&glob->lock);
106
107     list_add(&xfer->list, &ctx->opened_files);
108
109     TRACE("xfer created");
110
111     return xfer;
112
113   fail_xfer:
114     free(xfer);
115
116   fail_lock:
117     pthread_mutex_unlock(&glob->lock);
118
119     return NULL;
120 }
121
122 int
123 xfer_read(struct local_ctx *ctx, char *txt, unsigned int offset, unsigned int count, char *buf){
124     struct gnet_locator *xfer;
125
126     TRACE("txt: %s", txt);
127
128     if(!(xfer = create_xfer(ctx, txt))){
129         WARN("could not create xfer");
130         return -1;
131     }
132     
133     TRACE("reading %d bytes", count);
134     
135     return gnet_xfer_read((*ctx->global)->gnet, xfer, offset, count, buf);
136 }