📄 event.c
字号:
if (r <= 0) { t = time(0); wp(win, "* Transfer interrupted while sending \"%s\" to %s (%lu of %lu bytes in %lu seconds): %s\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t-task->p_time), r ? strerror(errno) : "connection lost?"); drw(win); if (info.logfile) { f = fopen(info.logfile, "a"); if (f) { start = strdup(ctime(&task->p_time)); start[strlen(start)-1] = 0; end = strdup(ctime(&t)); end[strlen(end)-1] = 0; fprintf(f, "SI %s %s \"%s\" %s\n", start, task->nick, task->lfn, end); fclose(f); free(start); free(end); } } fclose(task->f); task->d_time = t; task->state = INCOMPLETE; delsock(m->fd); return(1); } task->pos += n; /* update byte counts for bandwidth limiting */ bandwidth_register(&m->bw, n); bandwidth_register(&bwup, n); return(1);}/* ------------------------------------------------------------------------ *//* we have connected to a remote client in order to issue a GETLIST command. * The connection was initiated in scmds.c:sbrowse2acc(). */int initgetlist(WINDOW *win, sock_t *m){ int s = m->fd, r; char c; /* remote client should send a '1' (ASCII character 49) */ r = recv(s, &c, 1, 0); if (r <= 0) { wp(win, ""RED"* Error browsing %s: %s"WHITE"\n", directbrowse.nick, \ r ? strerror(errno) : "connection refused"); drw(win); directbrowse.state = FAILED; srch = 0; delsock(m->fd); return(1); } r = ssock(s, "GETLIST"); if (r <= 0) { wp(win, ""RED"* Error browsing %s: %s"WHITE"\n", directbrowse.nick, \ r ? strerror(errno) : "0 bytes written to socket"); drw(win); directbrowse.state = FAILED; srch = 0; delsock(m->fd); return(1); } /* still in CONNECTING state */ m->func = glistnick; /* wait for remote client to send its nick */ return(1);}/* ------------------------------------------------------------------------ *//* after we issue a GETLIST command, the remote client sends it nick before * sending its shared file list. */int glistnick(WINDOW *win, sock_t *m){ char *nick = NULL; FILE *f; /* we duplicate the file descriptor so the new descriptor can be closed * independently of the original one when fclose() is called. */ directbrowse.f = f = fdopen(dup(m->fd), "r"); /* remote client sends its nick as "<nick>\n" */ nick = nap_getline(f); /* nap_getline uses fgets() to read a line */ if (!nick) { wp(win, ""RED"* Error browsing %s: remote client did not send its nick"\ WHITE"\n", directbrowse.nick); drw(win); directbrowse.state = FAILED; srch = 0; fclose(f); /* closing the stream will also close the associated file descriptor, * but remember that this descriptor is a duplicate of m->fd, so * we can safely close m->fd. */ delsock(m->fd); return(1); } /* is this who we were expecting? */ if (strcasecmp(directbrowse.nick, nick) != 0) { wp(win, ""RED"* Error browsing %s: remote client reports nick as %s"\ WHITE"\n", directbrowse.nick, quote(nick)); drw(win); free(nick); directbrowse.state = FAILED; srch = 0; fclose(f); delsock(m->fd); return(1); } free(nick); wp(win, "* Receiving shared file list from %s...\n", directbrowse.nick); drw(win); directbrowse.state = IN_PROGRESS; m->func = glist; return(1);}/* ------------------------------------------------------------------------ *//* receive a shared file list from a remote client, one line per call */int glist(WINDOW *win, sock_t *m){ char *buf; char **tok; char *tmptok[7]; int cnt, i; FILE *f = directbrowse.f; /* remote client sends a list of files consisting of lines like * "<filename>" <md5> <size> <bitrate> <frequency> <time>\n * Last line is a \n by itself. */ buf = nap_getline(f); /* nap_getline will strip the trailing newline */ /* last line (single newline) will be returned as an empty string */ if (buf && *buf != '\0') { if (nvar("debug") == 2) { /* trailing newline was already stripped, so it won't show up here */ wp(win, ""DARK GREEN"<-- [from %d=%s] <%s>"WHITE"\n", m->fd, \ m->socknm, quote(buf)); drw(win); } tok = form_tokso(buf, &cnt); /* expect exactly 6 tokens */ if (cnt == 6) { /* srbrowse expects 7 tokens */ tmptok[0] = directbrowse.nick; for (i = 0; i < 6; i++) { tmptok[i+1] = tok[i]; } /* re-use the function that processes browse responses from the * server. The first arg is normally the file descriptor for the * socket connected to the server, but it isn't used by srbrowse * anyway. */ srbrowse(m->fd, buf, tmptok, 7, win); } for (i = 0; i < cnt; i++) free(tok[i]); free(tok); free(buf); } else { free(buf); fclose(f); directbrowse.state = COMPLETE; showresults(win, 0); /* also resets srch to 0 */ delsock(m->fd); return(1); } return(1);} /* ------------------------------------------------------------------------ *//* a remote client connected to us and issued a SENDLIST command so that it * can send us its shared file list. */int dosendlist(WINDOW *win, sock_t *m){ char *nick = NULL; FILE *f; /* were we expecting a browse list? */ if (directbrowse.state != REQUESTED) { delsock(m->fd); return(1); } /* "<nick>\n" immediately follows the SENDLIST command. */ directbrowse.f = f = fdopen(dup(m->fd), "r"); nick = nap_getline(f); /* nap_getline will strip leading spaces if there are any */ /* is this who we were expecting? */ if (!nick || strcasecmp(directbrowse.nick, nick) != 0) { if (nvar("debug") == 2) { wp(win, ""DARK GREEN"<-- [from %d=%s] Got unexpected SENDLIST from %s"\ " (%s)"WHITE"\n", m->fd, m->socknm, nick ? quote(nick):"?", \ getpeerip(m->fd)); drw(win); } free(nick); /* directbrowse.state remains REQUESTED */ fclose(f); delsock(m->fd); return(1); } free(nick); /* rename the connection */ free(m->socknm); m->socknm = strdup("dirbrowse"); if (nvar("debug") == 2) { wp(win, ""DARK GREEN"<-- [from %d=%s] Got SENDLIST from %s"WHITE"\n", \ m->fd, m->socknm, directbrowse.nick); } wp(win, "* Receiving shared file list from %s...\n", directbrowse.nick); drw(win); directbrowse.sk = m; directbrowse.state = IN_PROGRESS; m->func = glist; return(1);}/* ------------------------------------------------------------------------ *//* a remote client connected to us and issued a GETLIST command * (this is an outgoing direct browse connection) */int dogetlist(WINDOW *win, sock_t *m){ int s = m->fd, r; FILE *g; char *libraryfile; /* XXX if we limit the number of outgoing browse connections, * check that we are within the limit here. */ if (nvar("debug") == 2) { wp(win, ""DARK GREEN"<-- [from %d=%s] Got GETLIST"WHITE"\n", m->fd, m->socknm); drw(win); } /* rename the connection to "b #", where # is an integer */ free(m->socknm); m->socknm = strdup(gnum(2)); /* send "<mynick>\n" */ r = ssock(s, "%s\n", info.user); if (r <= 0) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: %s"WHITE"\n", \ r ? strerror(errno) : "0 bytes written to socket"); drw(win); } delsock(m->fd); return(1); } if (info.shared_filename) { libraryfile = strdup(info.shared_filename); } else { libraryfile = home_file(LIBRARYFILE); } g = fopen(libraryfile, "r"); if (!g) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: cannot open %s (%s)"WHITE"\n", \ libraryfile, strerror(errno)); drw(win); } delsock(m->fd); free(libraryfile); return(1); } free(libraryfile); m->btask = (outbrowse_t *) malloc(sizeof(outbrowse_t)); m->btask->g = g; m->func = slist; m->t = S_W; return(1);}/* ------------------------------------------------------------------------ *//* we have connected to a remote client to issue a SENDLIST command and * send our shared file list. (this is an outgoing direct browse connection) * The connection was initiated in scmds.c:sbrowse2req() and is named "b #", * where # is an integer. */int initsendlist(WINDOW *win, sock_t *m){ int s = m->fd, r; char c; FILE *g; char *libraryfile; /* remote client should send a '1' */ r = recv(s, &c, 1, 0); if (r <= 0) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: %s"WHITE"\n", \ r ? strerror(errno) : "connection refused"); drw(win); } delsock(m->fd); return(1); } /* send "SENDLIST" then "<mynick>\n" (this is what the Napster v2.0 BETA 8 * and BETA 9 clients seem to do; there is no space in between.) */ r = ssock(s, "SENDLIST"); r = ssock(s, "%s\n", info.user); if (r <= 0) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: %s"WHITE"\n", \ r ? strerror(errno) : "0 bytes written to socket"); drw(win); } delsock(m->fd); return(1); } if (info.shared_filename) { libraryfile = strdup(info.shared_filename); } else { libraryfile = home_file(LIBRARYFILE); } g = fopen(libraryfile, "r"); if (!g) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: cannot open %s (%s)"WHITE"\n", \ libraryfile, strerror(errno)); drw(win); } delsock(m->fd); free(libraryfile); return(1); } free(libraryfile); m->btask = (outbrowse_t *) malloc(sizeof(outbrowse_t)); m->btask->g = g; m->func = slist; m->t = S_W; return(1);}/* ------------------------------------------------------------------------ *//* send shared file list, one line per call */int slist(WINDOW *win, sock_t *m){ int s = m->fd, r; FILE *g; char *buf, *p; if (!m->btask) { delsock(m->fd); return(1); /* fatal error */ } g = m->btask->g; buf = nap_getline(g); /* nap_getline strips the trailing newline */ if (!buf) { /* EOF */ r = ssock(s, "\n"); /* terminate the list, ignore errors */ fclose(g); free(m->btask); delsock(m->fd); return(1); } if (*buf != '\"') { free(buf); return(1); /* skip headers and junk */ } for (p=buf; *p; p++) { if (*p == '/') *p = '\\'; } /* send the line; don't forget to terminate with a newline */ r = ssock(s, "%s\n", buf); if (r <= 0) { if (nvar("debug") == 2) { wp(win, ""RED"* Error sending list: %s"WHITE"\n", \ r ? strerror(errno) : "0 bytes written to socket"); drw(win); } free(buf); fclose(g); free(m->btask); delsock(m->fd); return(1); } free(buf); return(1);}/* receive a raw file on socket, after initget and gsize did the initial communication. */int gfile(WINDOW *win, sock_t *m){ char buf[2049], *st1, *end; /* note: don't need malloc for buf */ download_t *task = m->dtask; FILE *f; int n; time_t t; int r; char *lfn; memset(buf, 0, sizeof(buf)); n = recv(m->fd, buf, sizeof(buf)-1, 0); if (n > 0) { /* we got some bytes - write them to the local file */ write(fileno(task->f), buf, n); task->pos += n; /* update byte counts for bandwidth limiting */ bandwidth_register(&m->bw, n); bandwidth_register(&bwdown, n); } if (n<=0 || task->pos >= task->size) { /* end of file */ t = time(NULL); lfn = strdup(task->lfn); r = interrupt_download(win, task); switch (r) { case 1: wp(win, "* Download of \"%s\" from %s interrupted (%lu of %lu bytes in %lu seconds)\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t - task->p_time)); break; case 2: wp(win, "* Download of \"%s\" from %s interrupted, turd removed (%lu of %lu bytes in %lu seconds)\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t - task->p_time)); break; case 3: wp(win, "* Completed download of \"%s\" from %s (%lu of %lu bytes in %lu seconds)\n", task->fn, task->nick, (long)(task->pos-task->bsz), (long)(task->size-task->bsz), (long)(t - task->p_time)); break; default: break; } drw(win); if (info.logfile) { f = fopen(info.logfile, "a"); if (f) { st1 = strdup(ctime(&task->p_time)); st1[strlen(st1)-1] = 0; end = strdup(ctime(&t)); end[strlen(end)-1] = 0; fprintf(f, "%s %s %s \"%s\" %s\n", r==3 ? "R" : "RI", st1, task->nick, lfn, end); fflush(f); free(st1); free(end); } } free(lfn); delsock(m->fd); } return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -