⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 event.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
📖 第 1 页 / 共 3 页
字号:
    list_find(task, down, !strcasecmp(task->nick, nm) && !strcasecmp(task->rfn, rfn) && task->state==WAITING);  fn = ud_basename(rfn);  /* note: fn is a pointer into rfn! Do not free                          rfn while fn is still needed. */    if (!size)  {    rsock(m->fd, &buf);          wp(win, "* Error downloading \"%s\" from %s (returned a size of 0) " \        "[%s]\n", fn, nm, buf?quote(buf):"");    drw(win);    if (task) {      free(task->check);      task->state = FAILED;      task->d_time = time(0);    }    free(rfn);    free(nm);    delsock(m->fd);    return(1);  }    if (!task)  {    /* this error is frequently the result of a download request which timed       out before the remote client got in touch with us. We omit the        error message, since it is confusing and not useful */    /*    wp(win, "%s* Error: %s tried to send (push) \"%s\", but we did not request it!%s\n", RED, nm, fn, WHITE);	  drw(win); */    free(nm);    free(rfn);    delsock(m->fd);    return(1);  }  /* try to open local file for this download */  r = opendownloadfile(fn, &f, &lfn);  if (r==-1) {    wp(win, ""RED"* Error: could not open local file \"%s\": %s"WHITE"\n", lfn, strerror(errno));    drw(win);    free(lfn);  }  if (r==-1 || r==-2) {    free(nm);    free(rfn);    free(task->check);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }  free(nm);  free(rfn);  task->sk = m;  task->lfn = lfn;  task->f = f;  task->size = size;  task->bsz = 0;  task->pos = 0;  task->p_time = time(0);  task->state = IN_PROGRESS;  /* rename connection from "conn" to "d #", and connect it to this task */  free(m->socknm);  m->socknm = strdup(gnum(0));  m->dtask = task;  m->bwlimit = 1;  bandwidth_init(&m->bw);  m->func = gfile;  sv = findsock("server");  if (sv)    sendpack(sv->fd, NAP_DOWN, NULL);    /* send offset */  ssock(m->fd, "%lu", (long)0);    return(1);}/* try to open a port that is specified by the string   dataport. Dataport must either be a port number such as "6699" or a   range such as "6699-6799". Return port number used if successful,   or -1 if failure (with errno set). If port 0 is requested, return 0   without opening anything - this probably was configured by the user   if we're behind a firewall. */int initfserv(char *dataport){  struct sockaddr_in me;  int s, on = 1;  int port, first, last;  char *p;  if (!dataport)    return(0);    /* parse dataport */  first = last = strtol(dataport, &p, 10);  while (p && isspace(*p)) {    p++;  }  if (p && *p=='-') { /* range given? parse second part */    last = strtol(p+1, &p, 10);  }  if (!p || *p!='\0') { /* parse error */    errno = EINVAL;    return -1;  }  s = socket(AF_INET, SOCK_STREAM, 0);  if (s == -1)    return(-1);    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));  setkeepalive(s);    for (port = first; port <= last; port++) {    me.sin_addr.s_addr = INADDR_ANY;    me.sin_port = htons(port);    me.sin_family = AF_INET;        if (bind(s, (struct sockaddr *)&me, sizeof(me)) != -1) {       /* success */      listen(s, 5);      addsock(s, "fserv", S_R, gconn);      return(port);    }  }  return(-1);  /* overall failure */}void closefserv(){  sock_t *sk;    sk = findsock("fserv");  if (!sk)    return;    delsock(sk->fd);}/* We are about to upload a file to a remote client. We had to initiate * the connection because we are firewalled and cannot accept incoming * connections. The upload is in state CONNECTING. */int initsend(WINDOW *win, sock_t *m){  int s = m->fd, r;  upload_t *task = m->utask;  sock_t *sk;  struct stat st;  char c;  FILE *f;  /* read the initial "1" from remote client */  if (recv(s, &c, 1, 0) <= 0)  {    wp(win, "%s* Error sending file \"%s\" to %s: connection refused by remote client%s\n", RED, task->fn, task->nick, WHITE);    drw(win);    task->state=FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }  /* Open the local file for reading. Note: we already checked that     this file was in the shared library before we created this     task. Thus, the local file *should* exist. However, it might be     unreadable, or the library might be out of date. */  f = fopen(task->lfn, "rb");  if (!f) {    wp(win, ""RED"* \"%s\" not found (requested by %s)"WHITE"\n", task->lfn, task->nick);    drw(win);    task->state=FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }    /* determine file size */  fstat(fileno(f), &st);    r = ssock(s, "SEND");    /* send "mynick filename filesize" */  r = ssock(s, "%s \"%s\" %lu", info.user, task->rfn, st.st_size);    if (r <= 0)  {    wp(win, ""RED"* Error sending file (%s) to %s: %s%s"WHITE"", RED, task->rfn, task->nick, r ? strerror(errno) : "remote client is misconfigured");    drw(win);    sk = findsock("server");    if (sk)      sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick);    fclose(f);    task->state=FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }    /* go to state CONNECTING1, continue with ssize() */  task->state = CONNECTING1;  task->f = f;  task->size = st.st_size;    m->func = ssize;  m->t = S_R;    return(1);}/* continue what was started by initsend. Next the remote (firewalled)   client will send the byte offset. Upload's state is CONNECTING1. */int ssize(WINDOW *win, sock_t *m){  char buf[32];  int r;  upload_t *task = m->utask;  size_t bsz;  memset(buf, 0, 32);    r = recv(m->fd, buf, sizeof(buf), 0);    if (r<=0) {    wp(win, ""RED"* Error sending file \"%s\" to %s: %s"WHITE"\n", task->fn, task->nick, r ? strerror(errno) : "did not receive a proper offset");    drw(win);    fclose(task->f);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }  bsz = strtoul(buf, 0, 10);  if (bsz > task->size) {    wp(win, ""RED"* Error sending file \"%s\" to %s: illegal offset requested (%lu/%lu)"WHITE"\n", task->fn, task->nick, (long)bsz, (long)task->size);    drw(win);    fclose(task->f);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }    fseek(task->f, bsz, SEEK_SET);    /* go to state IN_PROGRESS */  task->bsz = bsz;  task->pos = bsz;  task->p_time = time(0);  task->state = IN_PROGRESS;    m->bwlimit = 1;  bandwidth_init(&m->bw);  m->func = sfile;  m->t = S_W;    wp(win, "* Sending file \"%s\" to %s (%lu bytes)\n", task->fn, task->nick, (long)(task->size - bsz));  drw(win);    return(1);}/* we have connected to a remote client and we are about to issue a request * for a file */int initget(WINDOW *win, sock_t *m){  int s = m->fd, r;  download_t *task = m->dtask;  /* state of task is CONNECTING */  download_t *elt;  sock_t *sk;  char ch;    /* remote client should send a '1' (ASCII character 49) */  r = recv(s, &ch, 1, 0);  if (r <= 0)  {    wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "connection refused", WHITE);    drw(win);    free(task->check);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }     /* make sure the task is not stale */  list_find(elt, down, elt==task);    if (!elt) {    delsock(m->fd);    return(1);  }  r = ssock(s, "GET");  r = ssock(s, "%s \"%s\" %lu", info.user, task->rfn, (long)0);    if (r <= 0)  {    wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "remote client misconfigured", WHITE);    drw(win);    sk = findsock("server");    if (sk)      sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick);    free(task->check);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }    m->func = gsize;  /*  m->t = S_R; */    return(1);}/* continue the GET started by initget, now receive remote host's answer */int gsize(WINDOW *win, sock_t *m){  char buf[32];  int i, s = m->fd;  download_t *task = m->dtask;  /* state is still CONNECTING */  sock_t *sk;  int r;  FILE *f;  char *lfn;  /* read file size. drscholl's napster spec says:   * "keep reading until you hit a character that is not a digit" */  for (i=0; i<31; i++)       /* but don't overflow buf[] ! */  {    r = recv(s, &buf[i], 1, MSG_PEEK);    if (r <= 0 && !i)    {      wp(win, "%s* Error getting file (%s) from %s: %s%s\n", RED, task->fn, task->nick, r ? strerror(errno) : "remote client misconfigured", WHITE);      drw(win);      sk = findsock("server");      if (sk)        sendpack(sk->fd, NAP_MISCONFIGURE, "%s", task->nick);      free(task->check);      task->state = FAILED;      task->d_time = time(0);      delsock(m->fd);      return(1);    }    /* abort only if first character is not a digit.     * this catches messages such as "INVALID REQUEST" or "FILE NOT SHARED"     * but does not barf on ID3 tags that follow the file size.     * (Before, an error was signaled if an alphabetic character      * followed 0 or more numeric characters. This caused a problem with     * mp3 files that start with ID3 tags.) -NBL */    if (!isdigit(buf[i]) && (i == 0))    {      recv(s, buf, 32, 0);      buf[31]=0;          /* make sure it's 0 terminated */      wp(win, ""RED"* Error getting \"%s\" from %s [%s]"WHITE"\n", task->fn, task->nick, quote(buf));      drw(win);      free(task->check);      task->state = FAILED;      task->d_time = time(0);      delsock(m->fd);      return(1);    }    if (!isdigit(buf[i]))      break;    recv(s, &buf[i], 1, 0);  }  /* get rid of the non-digit that was just read   * (or if i reached 31, make sure that buf[] is '\0'-terminated) */  buf[i] = '\0';   /* we need the debugging code here, since we didn't call rsock for this */  if (nvar("debug") == 2)  {    wp(win, ""DARK GREEN"<-- [from %d=%s] <%s>"WHITE"\n", s, m->socknm, quote(buf));    drw(win);  }    /* try to open local file for this download */  r = opendownloadfile(task->fn, &f, &lfn);  if (r==-1) {    wp(win, ""RED"* Error: could not open local file \"%s\": %s"WHITE"\n", lfn, strerror(errno));    drw(win);    free(lfn);  }  if (r==-1 || r==-2) {    free(task->check);    task->state = FAILED;    task->d_time = time(0);    delsock(m->fd);    return(1);  }  task->lfn = lfn;  task->f = f;  task->size = strtoul(buf, 0, 10);  task->bsz = 0;  task->pos = 0;  task->p_time = time(0);  task->state = IN_PROGRESS;  m->bwlimit = 1;  bandwidth_init(&m->bw);  m->func = gfile;  return(1);}/* Sending data to a remote client. State is IN_PROGRESS */int sfile(WINDOW *win, sock_t *m){  char buf[2048], *start, *end;  upload_t *task = m->utask;  FILE *f;  int n, r;  time_t t;  /* is this mix of low-level and high-level i/o safe? Why use FILE*   object if using low-level i/o? -PS */  n = read(fileno(task->f), buf, sizeof(buf));   if (n <= 0)  {    t = time(0);    wp(win, "* Finished sending \"%s\" to %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));    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, "S %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 = COMPLETE;    delsock(m->fd);    return(1);  }    r = send(m->fd, buf, n, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -