Don't fail transfer on TTHL failure.
[doldaconnect.git] / daemon / fnet-dc.c
index a99b680..df04b59 100644 (file)
@@ -136,7 +136,7 @@ struct dcpeer
     int extended;
     int direction;    /* Using the constants from transfer.h */
     int compress;
-    int hascurpos, notthl;
+    int hascurpos, fetchingtthl, notthl;
     struct tigertreehash tth;
     void *cprsdata;
     char *key;
@@ -575,8 +575,11 @@ static char *getadcid(struct dcpeer *peer)
 {
     char *buf;
     char *ret;
+    int isfilelist;
     
-    if((peer->transfer->hash != NULL) && isdchash(peer->transfer->hash) && supports(peer, "tthf"))
+    if(!wcscmp(peer->transfer->path, L"files.xml") || !wcscmp(peer->transfer->path, L"files.xml.bz2") || !wcscmp(peer->transfer->path, L"MyList.DcLst"))
+       isfilelist = 1;
+    if(!isfilelist && (peer->transfer->hash != NULL) && isdchash(peer->transfer->hash) && supports(peer, "tthf"))
     {
        buf = base32encode(peer->transfer->hash->buf, 24);
        ret = sprintf2("TTH/%.39s", buf);
@@ -673,6 +676,7 @@ static void requestfile(struct dcpeer *peer)
            sendadc(peer->sk, "0");
            sendadc(peer->sk, "-1");
            qstr(peer->sk, "|");
+           peer->fetchingtthl = 1;
            return;
        }
     }
@@ -726,23 +730,30 @@ static void sendmyinfo(struct socket *sk, struct fnetnode *fn)
     struct dchub *hub;
     char *buf;
     struct fnetnode *cfn;
-    int numhubs;
+    int hn1, hn2, hn3;
     
     hub = fn->data;
     qstrf(sk, "$MyINFO $ALL %s ", hub->nativenick);
     buf = tr(icswcstombs(confgetstr("dc", "desc"), DCCHARSET, "Charset_conv_failure"), "$_|_");
     qstrf(sk, "%s", buf);
-    numhubs = 0;
+    hn1 = hn2 = hn3 = 0;
     for(cfn = fnetnodes; cfn != NULL; cfn = cfn->next)
     {
        if((cfn->state == FNN_EST) || (cfn->state == FNN_HS))
-           numhubs++;
+       {
+           if(cfn->regstatus == FNNS_OP)
+               hn3++;
+           else if(cfn->regstatus == FNNS_REG)
+               hn2++;
+           else
+               hn1++;
+       }
     }
-    qstrf(sk, "<%s V:%s,M:%c,H:%i/0/0,S:%i>",
+    qstrf(sk, "<%s V:%s,M:%c,H:%i/%i/%i,S:%i>",
          DCIDTAG,
          DCIDTAGV,
          (tcpsock == NULL)?'P':'A',
-         numhubs,
+         hn1, hn2, hn3,
          confgetint("transfer", "slots")
          );
     qstrf(sk, "$ $");
@@ -993,7 +1004,7 @@ static void cmd_forcemove(struct socket *sk, struct fnetnode *fn, char *cmd, cha
     } else {
        freeargs = 0;
     }
-    if((newfn = fnetinitconnect(L"dc", args)) != NULL)
+    if((newfn = fnetinitconnect(L"dc", args, NULL)) != NULL)
     {
        linkfnetnode(newfn);
        putfnetnode(newfn);
@@ -1423,6 +1434,38 @@ static void cmd_usercommand(struct socket *sk, struct fnetnode *fn, char *cmd, c
     /* Do nothing for now. */
 }
 
+static void cmd_getpass(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
+{
+    struct dchub *hub;
+    struct wcspair *arg;
+    char *mbspw;
+    
+    hub = fn->data;
+    for(arg = fn->args; arg != NULL; arg = arg->next)
+    {
+       if(!wcscmp(arg->key, L"password"))
+           break;
+    }
+    if((arg == NULL) || ((mbspw = icwcstombs(arg->val, DCCHARSET)) == NULL))
+    {
+       killfnetnode(fn);
+       return;
+    }
+    qstrf(sk, "$MyPass %s|", mbspw);
+    free(mbspw);
+    fn->regstatus = FNNS_REG;
+    hubhandleaction(sk, fn, cmd, args);
+}
+
+static void cmd_logedin(struct socket *sk, struct fnetnode *fn, char *cmd, char *args)
+{
+    struct dchub *hub;
+    
+    hub = fn->data;
+    fn->regstatus = FNNS_OP;
+    hubhandleaction(sk, fn, cmd, args);
+}
+
 static void cmd_mynick(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
     struct dcexppeer *expect;
@@ -1475,7 +1518,8 @@ static void cmd_direction(struct socket *sk, struct dcpeer *peer, char *cmd, cha
            freedcpeer(peer);
            return;
        }
-       requestfile(peer);
+       if(peer->direction == TRNSD_DOWN)
+           requestfile(peer);
     } else {
        if(peer->wcsname == NULL)
        {
@@ -1572,6 +1616,7 @@ static void startul(struct dcpeer *peer)
 static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
     int size;
+    struct transfer *transfer;
     
     if(peer->transfer == NULL)
     {
@@ -1582,7 +1627,9 @@ static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, ch
     if(peer->transfer->size != size)
     {
        transfersetsize(peer->transfer, size);
+       transfer = peer->transfer;
        freedcpeer(peer);
+       trytransferbypeer(transfer->fnet, transfer->peerid);
        return;
     }
     startdl(peer);
@@ -1591,6 +1638,13 @@ static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, ch
 
 static void cmd_error(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
 {
+    if(peer->fetchingtthl)
+    {
+       peer->fetchingtthl = 0;
+       peer->notthl = 1;
+       requestfile(peer);
+       return;
+    }
     if((peer->transfer != NULL) && (peer->transfer->dir == TRNSD_DOWN))
     {
        transferseterror(peer->transfer, TRNSE_NOTFOUND);
@@ -2098,6 +2152,7 @@ static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char *
        peer->state = PEER_TTHL;
        peer->totalsize = numbytes;
        peer->curread = 0;
+       peer->fetchingtthl = 0;
        inittigertree(&peer->tth);
        handletthl(peer);
     } else if(!strcmp(argv[0], "file")) {
@@ -2467,6 +2522,8 @@ struct command hubcmds[] =
     {"$To:", cc(cmd_to)},
     {"$SR", cc(cmd_sr)},
     {"$UserCommand", cc(cmd_usercommand)},
+    {"$GetPass", cc(cmd_getpass)},
+    {"$LogedIn", cc(cmd_logedin)}, /* sic */
     {NULL, NULL}
 };