X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ftransfer.c;h=29ad45d22ea580fcf4bb7f8303c3e53114d507ba;hb=f945525047ca6dff44f4eb947d0238e259a436e8;hp=f5b6b50d4f268252c9d8bd6c3c5426eb18c4a629;hpb=6c6bc9ce5fcb3427089b1439abfba8ebda183f15;p=doldaconnect.git diff --git a/daemon/transfer.c b/daemon/transfer.c index f5b6b50..29ad45d 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 @@ -161,7 +162,7 @@ struct transfer *hasupload(struct fnet *fnet, wchar_t *peerid) for(transfer = transfers; transfer != NULL; transfer = transfer->next) { - if((transfer->fnet == fnet) && !wcscmp(transfer->peerid, peerid)) + if((transfer->dir == TRNSD_UP) && (transfer->fnet == fnet) && !wcscmp(transfer->peerid, peerid)) break; } return(transfer); @@ -292,8 +293,12 @@ void *transfergetdata(struct transfer *transfer, size_t *size) 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,7 +306,7 @@ 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; @@ -457,7 +462,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"); @@ -528,58 +533,6 @@ static void killfilter(struct transfer *transfer) transfer->filterbufsize = transfer->filterbufdata = 0; } -static char *findfilter(struct passwd *pwd) -{ - char *path, *filtername; - - if((path = sprintf2("%s/.dcdl-filter", pwd->pw_dir)) != NULL) - { - if(!access(path, X_OK)) - return(path); - free(path); - } - if((filtername = icwcstombs(confgetstr("transfer", "filter"), NULL)) == NULL) - { - flog(LOG_WARNING, "could not convert filter name into local charset: %s", strerror(errno)); - } else { - if(strchr(filtername, '/') == NULL) - { - if((path = sprintf2("/etc/%s", filtername)) != NULL) - { - if(!access(path, X_OK)) - { - free(filtername); - return(path); - } - free(path); - } - if((path = sprintf2("/usr/etc/%s", filtername)) != NULL) - { - if(!access(path, X_OK)) - { - free(filtername); - return(path); - } - free(path); - } - if((path = sprintf2("/usr/local/etc/%s", filtername)) != NULL) - { - if(!access(path, X_OK)) - { - free(filtername); - return(path); - } - free(path); - } - } else { - if(!access(filtername, X_OK)) - return(filtername); - } - free(filtername); - } - return(NULL); -} - static void handletranscmd(struct transfer *transfer, wchar_t *cmd, wchar_t *arg) { if(!wcscmp(cmd, L"status")) { @@ -653,7 +606,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; @@ -664,9 +617,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); @@ -679,7 +630,10 @@ int forkfilter(struct transfer *transfer) errno = EACCES; return(-1); } - if((filtername = findfilter(pwent)) == NULL) + filtername = findfile("dc-filter", pwent->pw_dir, 0); + if(filtername == NULL) + filtername = findfile(icswcstombs(confgetstr("transfer", "filter"), NULL, NULL), NULL, 0); + if(filtername == NULL) { flog(LOG_WARNING, "could not find filter for user %s", pwent->pw_name); errno = ENOENT; @@ -706,6 +660,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)); @@ -715,7 +675,7 @@ int forkfilter(struct transfer *transfer) { argv = NULL; argvsize = argvdata = 0; - buf = sprintf2("%i", transfer->size); + buf = sprintf2("%ji", (intmax_t)transfer->size); addtobuf(argv, filtername); addtobuf(argv, filename); addtobuf(argv, buf); @@ -798,10 +758,23 @@ static int run(void) static struct configvar myvars[] = { + /** The maximum number of simultaneously permitted uploads. A + * common hub rule is that you will need at least as many slots as + * the number of hubs to which you are connected. */ {CONF_VAR_INT, "slots", {.num = 3}}, + /** The TOS value to use for upload connections (see the TOS + * VALUES section). */ {CONF_VAR_INT, "ultos", {.num = SOCK_TOS_MAXTP}}, + /** The TOS value to use for download connections (see the TOS + * VALUES section). */ {CONF_VAR_INT, "dltos", {.num = SOCK_TOS_MAXTP}}, + /** The name of the filter script (see the FILES section for + * lookup information). */ {CONF_VAR_STRING, "filter", {.str = L"dc-filter"}}, + /** If true, only one upload is allowed per remote peer. This + * option is still experimental, so it is recommended to leave it + * off. */ + {CONF_VAR_BOOL, "ulquota", {.num = 0}}, {CONF_VAR_END} };