X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Fsearch.c;h=633e07ee7fd15b7e03e8c9efd63513e5042180c8;hb=4e564b59c7c565387c4907017dfacce2ef761f8a;hp=040ec30932ae571298b5bd3bfc937d823505f9ae;hpb=d3372da97568d5e1f35fa19787c8ec8af93a0435;p=doldaconnect.git diff --git a/daemon/search.c b/daemon/search.c index 040ec30..633e07e 100644 --- a/daemon/search.c +++ b/daemon/search.c @@ -1,6 +1,6 @@ /* * Dolda Connect - Modular multiuser Direct Connect-style client - * Copyright (C) 2004 Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (C) 2004 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include #include @@ -32,6 +31,7 @@ #include "log.h" #include "sysevents.h" #include "filenet.h" +#include "client.h" #include "search.h" #define TOK_STR 0 @@ -139,6 +139,19 @@ static struct wcslist *newsl(struct wcslist **list, wchar_t *str) return(ln); } +static int wcsexists(wchar_t *h, wchar_t *n) +{ + size_t hl = wcslen(h), nl = wcslen(n); + wchar_t lh[hl + 1], ln[nl + 1]; + int i; + + for(i = 0; i <= hl; i++) + lh[i] = towlower(h[i]); + for(i = 0; i <= nl; i++) + ln[i] = towlower(n[i]); + return(wcsstr(lh, ln) != NULL); +} + static void slmerge1(struct wcslist **list, wchar_t *str) { size_t len; @@ -395,10 +408,12 @@ static struct reinfo analyzere(wchar_t *re, wchar_t **endret, wchar_t endc) if(ret.begstr != NULL) { for(i = 0; (sinf.begstr[i] != L'\0') && (ret.begstr != L'\0') && (ret.begstr[i] == sinf.begstr[i]); i++); - if(i == 0) + if(i == 0) { free(ret.begstr); - else + ret.begstr = NULL; + } else { ret.begstr[i] = L'\0'; + } } free(sinf.begstr); } else { @@ -423,10 +438,12 @@ static struct reinfo analyzere(wchar_t *re, wchar_t **endret, wchar_t endc) maxlen = len1; } for(i = 1; (i <= minlen) && (ret.endstr[len1 - i] == sinf.endstr[len2 - i]); i++); - if(i == 1) + if(i == 1) { free(ret.endstr); - else if(i <= maxlen) + ret.endstr = NULL; + } else if(i <= maxlen) { wmemmove(ret.endstr, ret.endstr + (len1 - i) + 1, i); + } } free(sinf.endstr); } else { @@ -514,6 +531,11 @@ void putsexpr(struct sexpr *sexpr) if(sexpr->d.s != NULL) free(sexpr->d.s); } + if(sexpr->op == SOP_HASHIS) + { + if(sexpr->d.hash != NULL) + freehash(sexpr->d.hash); + } free(sexpr); } @@ -642,12 +664,29 @@ struct sexpr *parsesexpr(int argc, wchar_t **argv) sexpr->op = SOP_SIZEEQ; else sexpr->op = SOP_SIZEGT; - sexpr->d.n = wcstol(tok2->d.str + 2, NULL, 0); + sexpr->d.sz = wcstoll(tok2->d.str + 2, NULL, 0); sexpr->cost = 0; getsexpr(tok->d.se = sexpr); freetok(tok2); putsexpr(sexpr); done = 0; + } else if((st->type == TOK_STR) && !wcsncmp(st->d.str, L"H=", 2)) { + tok2 = poptok(&st); + pushtok(tok = newtok(), &st); + tok->type = TOK_SE; + sexpr = newsexpr(); + sexpr->op = SOP_HASHIS; + if((sexpr->d.hash = parsehash(tok2->d.str + 2)) == NULL) + { + freetok(tok2); + putsexpr(sexpr); + goto out_err; + } + sexpr->cost = 2; + getsexpr(tok->d.se = sexpr); + freetok(tok2); + putsexpr(sexpr); + done = 0; } else if((std >= 3) && (st->type == TOK_CP) && (st->next->type == TOK_SE) && (st->next->next->type == TOK_OP)) { freetok(poptok(&st)); tok = poptok(&st); @@ -741,8 +780,6 @@ struct wcslist *findsexprstrs(struct sexpr *sexpr) freesl(&l1); freesl(&l2); break; - case SOP_NOT: - break; case SOP_NAMERE: case SOP_LINKRE: list = regexfindstrings(sexpr->d.re.sre); @@ -1061,9 +1098,7 @@ static int srisvalid(struct srchres *sr, struct sexpr *sexpr) free(buf); return(!ret); case SOP_LINKRE: - p = sr->filename; - if(sr->fnet->filebasename != NULL) - p = sr->fnet->filebasename(p); + p = fnfilebasename(sr->filename); if((buf = icwcstombs(p, "UTF-8")) == NULL) return(0); ret = regexec(&sexpr->d.re.cre, buf, 0, NULL, 0); @@ -1072,16 +1107,18 @@ static int srisvalid(struct srchres *sr, struct sexpr *sexpr) case SOP_NAMESS: return(wcsexists(sr->filename, sexpr->d.s)); case SOP_LINKSS: - p = sr->filename; - if(sr->fnet->filebasename != NULL) - p = sr->fnet->filebasename(p); + p = fnfilebasename(sr->filename); return(wcsexists(p, sexpr->d.s)); case SOP_SIZELT: - return(sr->size < sexpr->d.n); + return(sr->size < sexpr->d.sz); case SOP_SIZEEQ: - return(sr->size == sexpr->d.n); + return(sr->size == sexpr->d.sz); case SOP_SIZEGT: - return(sr->size > sexpr->d.n); + return(sr->size > sexpr->d.sz); + case SOP_HASHIS: + if(sr->hash == NULL) + return(0); + return(hashcmp(sr->hash, sexpr->d.hash)); } return(0); } @@ -1112,6 +1149,8 @@ void freesrchres(struct srchres *sr) sr->srch->results = sr->next; sr->srch->numres--; } + if(sr->hash != NULL) + freehash(sr->hash); if(sr->filename != NULL) free(sr->filename); if(sr->peerid != NULL) @@ -1140,6 +1179,8 @@ struct srchres *dupsrchres(struct srchres *sr) new->filename = swcsdup(sr->filename); if(sr->fn != NULL) getfnetnode(new->fn = sr->fn); + if(sr->hash != NULL) + new->hash = duphash(sr->hash); return(new); }