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

📄 nap.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
📖 第 1 页 / 共 4 页
字号:
  readcfg(fn);    /* set defaults and prompt user for values that were left unset by     command line and config file. Note: if --build-only is given, we     do not need to generate this information. */    if (info.build != 2) {    r = set_defaults_interactive(fn);    if (r==-1) {      free(fn);      return(1);    }  }  free(fn);  if (info.shared_filename) {    libraryfile = strdup(info.shared_filename);  } else {    libraryfile = home_file(LIBRARYFILE);  }  if (info.build != -1) {    if (info.build)      {	wp(NULL, "Building library...\n");	if (buildflist(libraryfile, info.up) == -1) {	  wp(NULL, "There was an error building your library.\n");	  free(libraryfile);	  return(1);	}      } else if (!up_to_date(libraryfile, info.up))	{	  wp(NULL, "Your library is not up-to-date. Rebuilding...\n");	  if (buildflist(libraryfile, info.up) == -1) {	    wp(NULL, "There was an error building your library.\n");	    free(libraryfile);	    return(1);	  }	}        if (info.build == 2)      return(1);  }  fl = fopen(libraryfile, "r");  if (!fl)  {    wp(NULL, "Error reading %s: %s\nTry running \"nap -b\".\n", \       libraryfile, strerror(errno));    free(libraryfile);    return(1);  }  fclose(fl);  /* check for news on the client */  if (nvar_default("nonews", 0)==0 && !info.daemon) {    int timeout;    timeout = nvar_default("newstimeout", NEWSTIMEOUT);    wp(NULL, "Checking for new releases of nap... ");    r = checknv(1, timeout, &errmsg, &serial);    if (r==1 && serial) {      wp(NULL, "(o)kay, (q)uit, (d)on't prompt again: ");      ans = nap_getline(stdin);      if (ans[0]=='q') {	exit(0);      } else if (ans[0]=='d') {	nfilename = home_file(OLDNEWSFILE);	nfile = fopen(nfilename, "w");	free(nfilename);	if (nfile) {	  fprintf(nfile, "%s\n", serial);	  fclose(nfile);	}      }      free(ans);    } else if (r==1) {      wp(NULL, "Press return to continue.\n");      ans = nap_getline(stdin);      free(ans);    } else if (r==0) {      wp(NULL, "none found.\n");    } else if (r==2) {  /* old news, don't prompt */      /* do nothing */    } else {      wp(NULL, "failed.\n");    }  }    /* get server list from metaserver */  if (!info.sflag && nvar_default("nometa", 0)==0) {    char *url;    int timeout;    const char *errmsg;        url = getval("metaserver");    if (!url)       /* "randomly" pick a metaserver. */      url = ((time(NULL) % 2) ? METASERVER_1 : METASERVER_2);        timeout = nvar_default("metatimeout", METATIMEOUT);    if (timeout<0)      timeout = METATIMEOUT;        wp(NULL, "Reading server list from %s...\n", url);    r = metaserver(url, timeout, &errmsg);    switch (r) {    case -1:      wp(NULL, "Could not read server list: %s\n", errmsg);      break;    default:      wp(NULL, "Got %d servers.\n", r);      break;    }  }      /* note: we no longer check whether the download directory is     writable until we actually try to write something to it */    /* before connecting to the server, let's figure out our port number     for incoming upload requests. We have to find a port that's not     in use, and we have to communicate the port number to the server,     so that's why we do this early rather than later. -PS */  info.port = initfserv(info.dataport);  if (info.port == -1) {    if (strchr(info.dataport, '-')) {      wp(NULL, "Warning: could not open a port in the range %s: %s\n", info.dataport, strerror(errno));    } else {      wp(NULL, "Warning: could not open port %s: %s\n", info.dataport, strerror(errno));    }    wp(NULL, "Unable to serve incoming upload requests; will proceed as if firewalled\n");    info.port = 0;  } else {    wp(NULL, "Using port %d for incoming client connections\n", info.port);  }  if (info.noserver) {    goto noserver;  }  /* connect to a server */  srv = next_server(info.serverlist);  if (srv==NULL) {    wp(NULL, "No server specified\n");    return(1);  }  wp(NULL, "Getting best host...\n");  for (;;)  {    /* if we have reached the end of the server list, go back to beginning,        if info.reconnect is set - else give up */    if (srv==NULL) {      if (info.reconnect) {	srv = next_server(info.serverlist);	sleep(1);      } else {	return(1);      }    }    srv = strip(srv);   /* remove whitespace on both ends */    wp(NULL, "Trying %s\n", srv);    s = 2;    while (s == 2)      s = conn(srv);    if (s == -1)    {      srv = next_server(info.serverlist);      continue;    }      c = connection();    if (info.create)    {      wp(NULL, "Creating account...\n");      n = makeact(s, info.user, info.pass, info.port, c, info.email);      if (n == -1)      {        close(s);	srv = next_server(info.serverlist);        continue;      }      else       {	info.create = 0;        break; /* if we just created an account, we are already logged in */      }    }    else    {      wp(NULL, "Logging in...\n");      n = login(s, info.user, info.pass, info.port, c, info.email);      if (n == -1)      {        close(s);	srv = next_server(info.serverlist);        continue;      }      else       {        break;      }    }  }    /* announce our success */  {    struct sockaddr_in dst;    int frmlen = sizeof(dst);    if (!getpeername(s, (struct sockaddr *)&dst, &frmlen))      wp(NULL, "Connected to %s:%i\n", inet_ntoa(dst.sin_addr), ntohs(dst.sin_port));  }  addsock(s, "server", S_R, inserv);  t = glistn(info.user);  checkhotlist(s, t);  free(t);   if (nvar_default("savechannels", 0)) {    char *tmp = NULL, *fn;    msprintf(&tmp, CHANNELFILE, info.user);    fn = home_file(tmp);    free(tmp);    if (loadchans(s, fn)==-1) {      wp(wchan, ""RED"* Could not load channels from %s: %s"WHITE"\n", fn, \	 strerror(errno));    }     drw(wchan);    free(fn);  }  lfiles(s, libraryfile);  free(libraryfile); noserver:  /* we get here if skipped connecting to a server */  pipe(ipcs);    addsock(ipcs[0], "ipc", S_R, inipc);  if (!info.daemon)    addsock(0, "input", S_R, input);  initwin(info.nxterm);  signal(SIGUSR1, sigusr1);  if (!info.daemon) {    signal(SIGWINCH, tresize);    signal(SIGINT, sigint);  }  aliasfile = home_file(ALIASFILE);  handlerfile = home_file(HANDLERFILE);  loadaliases(aliasfile);  loadhandlers(handlerfile);  free(aliasfile);  free(handlerfile);  wp(wchan, "%s\n", title);  drw(wchan);  usleep(400000);  /* enter the main event loop. */  sockfunc(wchan, winput);    doquit();    return(1);}/* ---------------------------------------------------------------------- *//* Resolve the given string into an IP address in network byte   order. The string may either be an IP address in dot notation   ("127.0.0.1"), or a host name ("server.napster.com"). The answer is   written into *inp. Return non-zero if the address is valid, 0 (with   h_errno set) if not. */int resolve(const char *host, struct in_addr *inp){  struct hostent *hst;  int r;  r = inet_aton(host, inp);  if (r) {    return r;  }  hst = gethostbyname(host);  if (!hst) {    return 0;  } else if (hst->h_addrtype != AF_INET || hst->h_length != 4) {    /* not an IPv4 address??? */    h_errno = HOST_NOT_FOUND;    return 0;  }  memcpy(&inp->s_addr, hst->h_addr, 4);  return 1;}/* return the formatted IP address of the remote peer for the given   socket. The returned string is static and constant and will be   overwritten with the next call, or the next call to ntoa. */const char *getpeerip(int fd) {  int r;  struct sockaddr_in sa;  socklen_t l = sizeof(sa);  r = getpeername(fd, (struct sockaddr *)&sa, &l);  if (r==-1 || l<sizeof(sa) || sa.sin_family != AF_INET)    return "unknown";  else     return inet_ntoa(sa.sin_addr);}/* swap byte order of a (32 bit) word */unsigned long int swapl(unsigned long int x) {  return ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) \    | ((x & 0xff000000) >> 24);}/* just like connect(2), except that we time out after t seconds. No   timeout if t=0. Return value is -1 on error, else 0. If a timeout   occurred, we set errno to ETIMEDOUT. */int connect_t(int fd, struct sockaddr *serv_addr, int addlen, int t){  long flags;  int r;  fd_set fds;  struct timeval sec;  if (t==0) {    return connect(fd, serv_addr, addlen);  }  /* set to non-blocking */  flags = fcntl(fd, F_GETFL);  fcntl(fd, F_SETFL, flags | O_NONBLOCK);  r = connect(fd, serv_addr, addlen);  /* restore original flags */  fcntl(fd, F_SETFL, flags);  if (r == -1 && errno != EINPROGRESS) {    return -1;  }  /* wait up to timeout seconds until this fd becomes writeable */  FD_ZERO(&fds);  FD_SET(fd, &fds);  sec.tv_sec = t;  sec.tv_usec = 0;  r = select(fd+1, NULL, &fds, NULL, &sec);    if (r == -1) {  /* error */    return -1;  }  if (r == 0) {   /* timeout */    errno = ETIMEDOUT;    return -1;  }  return 0;}/* make connection to a napster server. As of 1.5.1, we drop support   for "napster-style" meta-servers, since they no longer seem to   exist. If "host" contains no ":", then use defines.h:DEFAULT_PORT   as the port */int conn(char *host){  int s;  struct sockaddr_in dst;  char *buf;  char *p;  int r;  int timeout;  unsigned short port;  timeout = nvar_default("connecttimeout", CONNECTTIMEOUT);  buf = strdup(host);  if (!buf) {    wp(wchan, "Error: %s\n", strerror(errno));    drw(wchan);    return -1;  }  p = strchr(buf, ':');  if (p) {    port = atoi(p+1);    *p = 0;  } else {    port = DEFAULT_PORT;  }      r = resolve(buf, &dst.sin_addr);  if (!r)  {    wp(wchan, "Error resolving host %s: %s\n", buf, hstrerror(h_errno));    drw(wchan);    free(buf);    return(-1);  }  dst.sin_port = htons(port);  dst.sin_family = AF_INET;    s = socket(AF_INET, SOCK_STREAM, 0);  if (s == -1)  {    wp(wchan, "Error creating socket: %s\n", strerror(errno));    drw(wchan);    free(buf);    return(-1);  }    wp(wchan, "Connecting...\n");  drw(wchan);  if (connect_t(s, (struct sockaddr *)&dst, sizeof(dst), timeout) == -1)  {    if (!lpbrk) {      wp(wchan, "Error connecting to %s:%d: %s\n", buf, port, strerror(errno));      drw(wchan);    }    close(s);    free(buf);    return(-1);  }  setkeepalive(s);    free(buf);  return(s);}int login(int s, char *user, char *pass, int data, int conn, char *email){  char *t1;  phead_t *rcv;  int r;  int timeout;  char *identity = getval("identity");  timeout = nvar_default("connecttimeout", CONNECTTIMEOUT);  if (timeout==0) {    timeout=-1;  }  r = sendpack(s, NAP_LOGIN, "%s %s %i \"%s\" %i", user, pass, data, identity ? identity : IDENTITY, conn);  if (r<0) {    wp(wchan, "Error: %s\n", strerror(errno));    drw(wchan);    return(-1);  }  r = recvpack_t(s, &t1, &rcv, timeout);  while (r == -2) {    r = recvpack_t(s, &t1, &rcv, timeout);  }  if (r == -1) {    wp(wchan, "Error while receiving data: %s\n", strerror(errno));    drw(wchan);    return(-1);  } else if (r == -3) {    wp(wchan, "Error: unexpected end of file from server\n");    drw(wchan);    return(-1);  } else if (r == -4) {    wp(wchan, "Error: Connection timed out\n");    drw(wchan);    return(-1);  }  if (rcv->op == NAP_LOGERROR)  {    wp(wchan, "Error: %s\n", t1);    drw(wchan);    free(t1);    free(rcv);    return(-1);  }  /* the following works for opennap and slavanap. The "email address"     they send is of the form anon@servername. Slavanap also sends an     additional integer. */  if (strncmp(t1, "anon@", 5)==0) {    char *p = strchr(t1, ' ');    if (p) {      *p = 0;    }    wp(wchan, "Server's name appears to be %s\n", t1+5);    drw(wchan);  }  free(t1);  free(rcv);    return r;}int makeact(int s, char *user, char *pass, int data, int conn, char *email){  char *t1=NULL;  phead_t *rcv;  int r;  int timeout;  char *identity = getval("identity");  timeout = nvar_default("connecttimeout", CONNECTTIMEOUT);  if (timeout==0) {    timeout=-1;  }  r = sendpack(s, NAP_MKUSER, user);  if (r<0) {    wp(wchan, "Error: %s\n", strerror(errno));    drw(wchan);    return(-1);  }    r = recvpack_t(s, &t1, &rcv, timeout);  while (r == -2) {    r = recvpack_t(s, &t1, &rcv, timeout);  }  if (r == -1) {    wp(wchan, "Error while receiving data: %s\n", strerror(errno));    drw(wchan);    return(-1);  } else if (r == -3) {    wp(wchan, "Error: unexpected end of file from server\n");    drw(wchan);    return(-1);  } else if (r == -4) {    wp(wchan, "Error: Connection timed out\n");    drw(wchan);    return(-1);  }    if (rcv->op == NAP_UNTK)  {    wp(wchan, "Error: Username taken\n");    drw(wchan);    free(t1);    free(rcv);    return(-1);  }  else if (rcv->op == NAP_UNBAD)  {

⌨️ 快捷键说明

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