X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ftransfer.c;h=9ad6efea235cf4fed4b27b60cd5cf156c011ea26;hb=96be906d7e4bf2bfa84a926e1b1b149cdd708021;hp=d364b570116e345c565fef8b8e3aa77aff30ef47;hpb=529e3a4af16cc0ce2368b828a5fa7a8bcce4d6ba;p=doldaconnect.git diff --git a/daemon/transfer.c b/daemon/transfer.c index d364b57..9ad6efe 100644 --- a/daemon/transfer.c +++ b/daemon/transfer.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 @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -125,22 +126,19 @@ struct transfer *newtransfer(void) return(new); } -void transferattach(struct transfer *transfer, struct transferiface *iface, void *data) +void transferattach(struct transfer *transfer, struct socket *dpipe) { - if(transfer->iface != NULL) - transferdetach(transfer); - transfer->iface = iface; - transfer->ifacedata = data; + transferdetach(transfer); + getsock(transfer->datapipe = dpipe); } void transferdetach(struct transfer *transfer) { - if(transfer->iface != NULL) - { - transfer->iface->detach(transfer, transfer->ifacedata); - transfer->iface = NULL; - transfer->ifacedata = NULL; + if(transfer->datapipe != NULL) { + closesock(transfer->datapipe); + putsock(transfer->datapipe); } + transfer->datapipe = NULL; } struct transfer *finddownload(wchar_t *peerid) @@ -149,7 +147,7 @@ struct transfer *finddownload(wchar_t *peerid) for(transfer = transfers; transfer != NULL; transfer = transfer->next) { - if((transfer->dir == TRNSD_DOWN) && (transfer->iface == NULL) && !wcscmp(peerid, transfer->peerid)) + if((transfer->dir == TRNSD_DOWN) && (transfer->datapipe == NULL) && !wcscmp(peerid, transfer->peerid)) break; } return(transfer); @@ -167,7 +165,7 @@ struct transfer *hasupload(struct fnet *fnet, wchar_t *peerid) return(transfer); } -struct transfer *newupload(struct fnetnode *fn, struct fnet *fnet, wchar_t *nickid, struct transferiface *iface, void *data) +struct transfer *newupload(struct fnetnode *fn, struct fnet *fnet, wchar_t *nickid, struct socket *dpipe) { struct transfer *transfer; @@ -181,7 +179,7 @@ struct transfer *newupload(struct fnetnode *fn, struct fnet *fnet, wchar_t *nick transfer->dir = TRNSD_UP; if(fn != NULL) getfnetnode(transfer->fn = fn); - transferattach(transfer, iface, data); + transferattach(transfer, dpipe); linktransfer(transfer); bumptransfer(transfer); return(transfer); @@ -201,8 +199,7 @@ void resettransfer(struct transfer *transfer) { if(transfer->dir == TRNSD_DOWN) { - if(transfer->iface != NULL) - transferdetach(transfer); + transferdetach(transfer); killfilter(transfer); transfersetstate(transfer, TRNS_WAITING); transfersetactivity(transfer, L"reset"); @@ -231,21 +228,33 @@ static void transexpire(int cancelled, struct transfer *transfer) transfer->timeout = 0; } -static void transferread(struct socket *sk, struct transfer *transfer) +static void localread(struct socket *sk, struct transfer *transfer) { - if(sockgetdatalen(sk) >= 65536) - sk->ignread = 1; - if((transfer->iface != NULL) && (transfer->iface->gotdata != NULL)) - transfer->iface->gotdata(transfer, transfer->ifacedata); + void *buf; + size_t blen; + + if(transfer->datapipe != NULL) { + buf = sockgetinbuf(sk, &blen); + sockqueue(transfer->datapipe, buf, blen); + if(sockqueuesize(transfer->datapipe) >= 65536) + sockblock(sk, 1); + else + sockblock(sk, 0); + } else { + if(sockgetdatalen(sk) >= 65536) + sockblock(sk, 1); + } } -static void transferwrite(struct socket *sk, struct transfer *transfer) +static void localwrite(struct socket *sk, struct transfer *transfer) { - if((transfer->iface != NULL) && (transfer->iface->wantdata != NULL)) - transfer->iface->wantdata(transfer, transfer->ifacedata); + void *buf; + size_t blen; + + } -static void transfererr(struct socket *sk, int errno, struct transfer *transfer) +static void localerr(struct socket *sk, int errno, struct transfer *transfer) { if((transfer->iface != NULL) && (transfer->iface->endofdata != NULL)) transfer->iface->endofdata(transfer, transfer->ifacedata); @@ -275,9 +284,9 @@ void transferendofdata(struct transfer *transfer) } } -size_t transferdatasize(struct transfer *transfer) +ssize_t transferdatasize(struct transfer *transfer) { - return(sockqueuesize(transfer->localend)); + return(sockqueueleft(transfer->localend)); } void *transfergetdata(struct transfer *transfer, size_t *size) @@ -286,14 +295,17 @@ void *transfergetdata(struct transfer *transfer, size_t *size) if(transfer->localend == NULL) return(NULL); - transfer->localend->ignread = 0; time(&transfer->activity); if((buf = sockgetinbuf(transfer->localend, size)) == NULL) return(NULL); if((transfer->endpos >= 0) && (transfer->curpos + *size >= transfer->endpos)) { - *size = transfer->endpos - transfer->curpos; - buf = srealloc(buf, *size); + if((*size = transfer->endpos - transfer->curpos) == 0) { + free(buf); + buf = NULL; + } else { + buf = srealloc(buf, *size); + } } transfer->curpos += *size; bytesupload += *size; @@ -301,12 +313,11 @@ void *transfergetdata(struct transfer *transfer, size_t *size) return(buf); } -void transferprepul(struct transfer *transfer, size_t size, size_t start, size_t end, struct socket *lesk) +void transferprepul(struct transfer *transfer, off_t size, off_t start, off_t end, struct socket *lesk) { transfersetsize(transfer, size); transfer->curpos = start; transfer->endpos = end; - lesk->ignread = 1; transfersetlocalend(transfer, lesk); } @@ -321,7 +332,7 @@ void transferstartul(struct transfer *transfer, struct socket *sk) transfersetstate(transfer, TRNS_MAIN); socksettos(sk, confgetint("transfer", "ultos")); if(transfer->localend != NULL) - transfer->localend->ignread = 0; + transferread(transfer->localend, transfer); } void transfersetlocalend(struct transfer *transfer, struct socket *sk) @@ -330,9 +341,9 @@ void transfersetlocalend(struct transfer *transfer, struct socket *sk) putsock(transfer->localend); getsock(transfer->localend = sk); sk->data = transfer; - sk->readcb = (void (*)(struct socket *, void *))transferread; - sk->writecb = (void (*)(struct socket *, void *))transferwrite; - sk->errcb = (void (*)(struct socket *, int, void *))transfererr; + sk->readcb = (void (*)(struct socket *, void *))localread; + sk->writecb = (void (*)(struct socket *, void *))localwrite; + sk->errcb = (void (*)(struct socket *, int, void *))localerr; } static int tryreq(struct transfer *transfer) @@ -457,7 +468,7 @@ void transfersetnick(struct transfer *transfer, wchar_t *newnick) CBCHAINDOCB(transfer, trans_ac, transfer, L"nick"); } -void transfersetsize(struct transfer *transfer, int newsize) +void transfersetsize(struct transfer *transfer, off_t newsize) { transfer->size = newsize; CBCHAINDOCB(transfer, trans_ac, transfer, L"size"); @@ -601,7 +612,7 @@ static void filterexit(pid_t pid, int status, void *data) int forkfilter(struct transfer *transfer) { - char *filtername, *filename, *peerid, *buf; + char *filtername, *filename, *peerid, *buf, *p; wchar_t *wfilename; struct passwd *pwent; pid_t pid; @@ -612,9 +623,7 @@ int forkfilter(struct transfer *transfer) struct wcspair *ta; char *rec, *val; - wfilename = transfer->path; - if(transfer->fnet->filebasename != NULL) - wfilename = transfer->fnet->filebasename(wfilename); + wfilename = fnfilebasename(transfer->path); if(transfer->auth == NULL) { flog(LOG_WARNING, "tried to fork filter for transfer with NULL authhandle (tranfer %i)", transfer->id); @@ -657,6 +666,12 @@ int forkfilter(struct transfer *transfer) peerid = sprintf2("utf8-%s", buf); free(buf); } + for(p = filename; *p; p++) { + if(*p == '/') + *p = '_'; + else if((p == filename) && (*p == '.')) + *p = '_'; + } if((pid = forksess(transfer->owner, transfer->auth, filterexit, NULL, FD_PIPE, 0, O_WRONLY, &inpipe, FD_PIPE, 1, O_RDONLY, &outpipe, FD_FILE, 2, O_RDWR, "/dev/null", FD_END)) < 0) { flog(LOG_WARNING, "could not fork session for filter for transfer %i: %s", transfer->id, strerror(errno)); @@ -666,7 +681,7 @@ int forkfilter(struct transfer *transfer) { argv = NULL; argvsize = argvdata = 0; - buf = sprintf2("%zi", transfer->size); + buf = sprintf2("%ji", (intmax_t)transfer->size); addtobuf(argv, filtername); addtobuf(argv, filename); addtobuf(argv, buf); @@ -707,7 +722,7 @@ int forkfilter(struct transfer *transfer) * the fd, and thus it closes it. Until I can find out whyever the * kernel gives a POLLIN on the fd (if I can at all...), I'll just * set ignread on insock for now. */ - insock->ignread = 1; +/* sockblock(insock, 1); */ transfer->filter = pid; transfersetlocalend(transfer, insock); getsock(transfer->filterout = outsock);