10 #include <lufs/proto.h>
21 static char path_buf[MAX_PATH];
24 delete_result(struct result *res){
25 struct list_head *p, *tmp;
26 struct gnet_locator *loc;
28 list_for_each_safe(p, tmp, &res->locators){
29 loc = list_entry(p, struct gnet_locator, list);
41 delete_search(struct search *srch){
42 struct list_head *p, *tmp;
44 list_for_each_safe(p, tmp, &srch->results)
45 delete_result(list_entry(p, struct result, list));
47 list_del(&srch->list);
53 find_search_by_txt(struct global_ctx *glob, char *txt){
57 list_for_each(p, &glob->searches){
58 srch = list_entry(p, struct search, list);
59 if(!strcmp(srch->txt, txt)){
60 TRACE("search found");
65 TRACE("search not found");
71 find_search_by_id(struct global_ctx *glob, unsigned long id){
75 list_for_each(p, &glob->searches){
76 srch = list_entry(p, struct search, list);
78 TRACE("search found");
83 TRACE("search not found");
89 find_result_by_name(struct search *srch, char *name){
93 list_for_each(p, &srch->results){
94 r = list_entry(p, struct result, list);
96 if(!strcmp(r->name, name)){
97 TRACE("result found");
102 TRACE("result not found");
108 static struct result*
109 find_result_by_locator(struct search *srch, struct gnet_locator *loc){
113 list_for_each(p, &srch->results){
114 r = list_entry(p, struct result, list);
116 if(!(strcmp(r->name, loc->name)) && (r->size == loc->size)){
117 TRACE("result found");
122 TRACE("result not found");
128 search_hit(void *c, struct gnet_locator *loc, unsigned long id){
129 struct global_ctx *glob = c;
132 struct gnet_locator *new_loc;
133 struct lufs_fattr fattr;
135 TRACE("got a search hit, search id=%lx, file=%s", id, loc->name);
137 pthread_mutex_lock(&glob->lock);
139 if(!(srch = find_search_by_id(glob, id))){
140 WARN("unknown search id %lx", id);
144 if(!(res = find_result_by_locator(srch, loc))){
147 if(!(res = malloc(sizeof(struct result)))){
148 WARN("could not allocate result: %s", strerror(errno));
152 memset(res, 0, sizeof(struct result));
154 if(!(res->name = malloc(strlen(loc->name) + 1))){
155 WARN("could not allocate result: %s", strerror(errno));
160 INIT_LIST_HEAD(&res->locators);
161 res->stamp = time(NULL);
162 res->size = loc->size;
163 strcpy(res->name, loc->name);
164 list_add(&res->list, &srch->results);
167 if(!(new_loc = malloc(sizeof(struct gnet_locator)))){
168 WARN("could not allocate result locator");
172 memset(new_loc, 0, sizeof(struct gnet_locator));
174 new_loc->name = res->name;
175 memcpy(new_loc->ip, loc->ip, 4);
176 memcpy(new_loc->guid, loc->guid, 16);
177 new_loc->port = loc->port;
178 new_loc->index = loc->index;
179 new_loc->size = loc->size;
180 new_loc->bwidth = loc->bwidth;
182 list_add(&new_loc->list, &res->locators);
185 if(snprintf(path_buf, MAX_PATH, "%s/%s", SEARCH_DIR, srch->txt) >= MAX_PATH){
186 WARN("search string too long");
190 TRACE("adding %s to %s", loc->name, path_buf);
192 memset(&fattr, 0, sizeof(struct lufs_fattr));
193 fattr.f_nlink = res->nr_locators;
194 fattr.f_uid = fattr.f_gid = 1;
195 fattr.f_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IFREG;
196 fattr.f_mtime = fattr.f_ctime = fattr.f_atime = res->stamp;
197 fattr.f_size = res->size;
199 lu_vtree_add(glob->vtree, path_buf, res->name, NULL, &fattr, NULL);
202 pthread_mutex_unlock(&glob->lock);
206 start_search(struct local_ctx *ctx, char *txt){
208 struct global_ctx *glob = *ctx->global;
210 TRACE("starting search for \"%s\"", txt);
212 if(!(srch = malloc(sizeof(struct search))))
215 memset(srch, 0, sizeof(struct search));
217 if(!(srch->txt = malloc(strlen(txt) + 1)))
220 strcpy(srch->txt, txt);
222 INIT_LIST_HEAD(&srch->results);
223 srch->stamp = time(NULL);
225 if(gnet_start_search(glob->gnet, txt, search_hit, glob, 0, &srch->id) < 0){
226 WARN("could not start gnet search: %s", strerror(errno));
230 pthread_mutex_lock(&glob->lock);
232 list_add_tail(&srch->list, &glob->searches);
234 pthread_mutex_unlock(&glob->lock);
236 TRACE("search started");