/* get the best filename for the uploaded file */ static char *fetch_get_filename(fetch_curl_t *ft, const char *effective_url) { if (ft->contentname != NULL) return getsendname(ft->contentname); if (effective_url != NULL) return getsendname(effective_url); return getsendname(ft->url); }
/* search the DDC transfer a user wants to resume */ unsigned int t_find_resume(const char *nick, const char *filename, const char *localport, const char *bytes, char *token) { char *sendnamestr; transfer *guess; transfer *tr; off_t len; guess = NULL; for (tr = irlist_get_head(&gdata.trans); tr; tr = irlist_get_next(tr)) { if ((tr->tr_status != TRANSFER_STATUS_LISTENING) && (tr->tr_status != TRANSFER_STATUS_RESUME)) continue; if (strcasecmp(tr->caps_nick, nick)) continue; /* the filename can be converted */ if (guess == NULL) guess = tr; if (strcasestr(tr->xpack->file, filename)) break; if (tr->con.localport == (unsigned)atoi(localport)) break; } if (tr == NULL) { if (guess != NULL) { outerror(OUTERROR_TYPE_WARN, "Guessed transfer that %s on %s tried to resume!", nick, gnetwork->name); outerror(OUTERROR_TYPE_WARN, "resume trying %s, %s, %d", nick, filename, atoi(localport)); tr = guess; } else { t_find_debug(nick, filename, localport); return 1; } } len = atoull(bytes); if (len >= tr->xpack->st_size) { notice(nick, "You can't resume the transfer at a point greater than the size of the file"); ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "XDCC [%02i:%s on %s]: Resume attempted beyond end of file ( %" LLPRINTFMT "d >= %" LLPRINTFMT "d )", tr->id, tr->nick, gnetwork->name, len, tr->xpack->st_size); return 1; } t_setresume(tr, bytes); sendnamestr = getsendname(filename); if ((tr->tr_status == TRANSFER_STATUS_RESUME) && (token != NULL)) { privmsg_fast(nick, IRC_CTCP "DCC ACCEPT %s %s %s %s" IRC_CTCP, sendnamestr, localport, bytes, token); /* NOTRANSLATE */ } else { privmsg_fast(nick, IRC_CTCP "DCC ACCEPT %s %s %s" IRC_CTCP, sendnamestr, localport, bytes); /* NOTRANSLATE */ } mydelete(sendnamestr); ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "XDCC [%02i:%s on %s]: Resumed at %" LLPRINTFMT "dK", tr->id, tr->nick, gnetwork->name, tr->startresume/1024); return 0; }
/* send DCC command to start download */ void t_start_dcc_send(transfer *tr) { char *dccdata; char *sendnamestr; updatecontext(); sendnamestr = getsendname(tr->xpack->file); dccdata = setup_dcc_local(&tr->con.local); if (tr->passive_dcc) { bzero((char *) &(tr->con.local), sizeof(tr->con.local)); privmsg_fast(tr->nick, IRC_CTCP "DCC SEND %s %s %" LLPRINTFMT "d %u" IRC_CTCP, /* NOTRANSLATE */ sendnamestr, dccdata, tr->xpack->st_size, tr->id); } else { privmsg_fast(tr->nick, IRC_CTCP "DCC SEND %s %s %" LLPRINTFMT "d" IRC_CTCP, /* NOTRANSLATE */ sendnamestr, dccdata, tr->xpack->st_size); ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "listen on port %d for %s (%s on %s)", tr->con.localport, tr->nick, tr->hostname, gnetwork->name); } mydelete(dccdata); mydelete(sendnamestr); }
/* check permissions and setup the upload transfer */ void upload_start(const char *nick, const char *hostname, const char *hostmask, const char *filename, const char *remoteip, const char *remoteport, const char *bytes, char *token) { upload *ul; char *uploaddir; char *tempstr; off_t len; updatecontext(); len = atoull(bytes); if (invalid_upload(nick, hostmask, len)) return; uploaddir = get_uploaddir(hostmask); if (uploaddir == NULL) { error_upload_start(nick, hostmask, "no uploaddir", "No uploaddir defined."); return; } if (disk_full(uploaddir) != 0) { error_upload_start(nick, hostmask, "disk full", "not enough free space on disk"); return; } if (file_uploading(filename) != 0) { error_upload_start(nick, hostmask, "upload running", "I'm already getting this file"); return; } if (max_uploads_reached() != 0) { error_upload_start(nick, hostmask, "too many uploads", "I'm already getting too many files"); return; } ul = irlist_add(&gdata.uploads, sizeof(upload)); l_initvalues(ul); ul->file = mystrdup(getfilename(filename)); ul->con.family = (strchr(remoteip, ':')) ? AF_INET6 : AF_INET; ul->con.remoteaddr = mystrdup(remoteip); ul->con.remoteport = atoi(remoteport); ul->totalsize = len; ul->nick = mystrdup(nick); ul->hostname = mystrdup(hostname); ul->uploaddir = mystrdup(uploaddir); ul->net = gnetwork->net; qupload_started(gnetwork->net, nick); tempstr = getsendname(ul->file); ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "DCC Send Accepted from %s on %s: %s (%" LLPRINTFMT "dkB)", nick, gnetwork->name, tempstr, (ul->totalsize / 1024)); mydelete(tempstr); if (gdata.mirc_dcc64) if (ul->totalsize > 0xFFFFFFFFL) ul->mirc_dcc64 = 1; if (ul->con.remoteport > 0U) { l_establishcon(ul); } else { /* Passive DCC */ l_setup_passive(ul, token); } }
static int l_setup_listen(upload * const l) { char *tempstr; char *msg; unsigned int rc; updatecontext(); rc = irc_open_listen(&(l->con)); if (rc != 0) { l_closeconn(l, "Connection Lost", 0); return 1; } msg = setup_dcc_local(&(l->con.local)); tempstr = getsendname(l->file); privmsg_fast(l->nick, IRC_CTCP "DCC SEND %s %s %" LLPRINTFMT "d %u" IRC_CTCP, /* NOTRANSLATE */ tempstr, msg, l->totalsize, l->token); mydelete(msg); msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(l->con.local.sa)); ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC SEND sent to %s on %s, waiting for connection on %s", l->nick, gnetwork->name, msg); mydelete(tempstr); mydelete(msg); l->ul_status = UPLOAD_STATUS_LISTENING; return 0; }
/* open new port for incoming connection */ int l_setup_passive(upload * const l, char *token) { char *tempstr; struct stat s; size_t len; int retval; updatecontext(); /* strip T */ if (token != NULL) { len = strlen(token) - 1; if (token[len] == 'T') token[len] = '\0'; l->token = atoi(token); } else { l->token = 0; } retval = l_setup_file(l, &s); if (retval == 2) { tempstr = getsendname(l->file); privmsg_fast(l->nick, IRC_CTCP "DCC RESUME %s %d %" LLPRINTFMT "d %u" IRC_CTCP, /* NOTRANSLATE */ tempstr, l->con.remoteport, s.st_size, l->token); mydelete(tempstr); l->con.connecttime = gdata.curtime; l->con.lastcontact = gdata.curtime; l->ul_status = UPLOAD_STATUS_RESUME; return 0; } if (retval != 0) { return 1; } return l_setup_listen(l); }