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

📄 nap.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
📖 第 1 页 / 共 4 页
字号:
    }  }  free(ans);  ans = NULL;  conn = nvar("connection");  if (conn < 0 || conn > 10) {    wp(NULL, "Invalid connection given - using 0\n");    chset("connection", NULL);    conn = 0;  }    if (!getval("maxuploads")) {    ans = itoa(ups[conn]);    chset("maxuploads", ans);    wp(NULL, "Allowing %s simultaneous uploads\n", ans);    free(ans);    ans = NULL;  }  /* if anything changed, and if non-null fn was given, ask user if he     wants to save changes. */  if (fn && !info.daemon) {    r = stat(fn, &st);  /* r!=0 if config file does not yet exist */        if (r || changes) {      if (r) {	wp(NULL, "Create a config file (%s) with these settings? [y] ", fn);      } else {	wp(NULL, "Save these settings to your config file (%s)? [y] ", fn);      }      ans = nap_getline(stdin);      if (ans && (!strcmp(ans, "") || !strcasecmp(ans, "y") || !strcasecmp(ans, "yes"))) {	r = savesets(fn);	if (r==-1) {	  wp(NULL, "Error saving config file: %s\n", strerror(errno));	}      } else {	wp(NULL, "Not saving.\n");      }      free(ans);      ans = NULL;    }  }  return 0;}/* print to a newly allocated string *str. If *str is non-NULL, free    the old content. */int msprintf(char **str, const char *fmt, ...){  va_list args;  int r;  if (*str != NULL) {    free(*str);    *str = NULL;  }  va_start(args, fmt);  r = vasprintf(str, fmt, args);  va_end(args);  if (r<0) {    return -1;  } else {    /* Note: the info page for libc claims that asprintf (thus       vasprintf) returns the number of characters *allocated*, but it       actually seems to return the number of characters *printed*       (not including the terminating 0). Thus it seems that we could       return r, but to be safe and unambiguous, we explicitly       calculate strlen(*str). */    return strlen(*str);  }}/* count the number of occurences of character t in string buf *//* not used */int strcnt(char *buf, char t){  int i,r;    for (i=0,r=0;buf[i];i++)    if (buf[i] == t)      r++;    return(r);}static struct option longopts[] = {  {"help",        0, 0, 'h'},  {"version",     0, 0, 'v'},  {"daemon",      0, 0, 'q'},  {"autorestart", 0, 0, 'a'},  {"build-only",  0, 0, 'B'},  {"build",       0, 0, 'b'},  {"nobuild",     0, 0, 'N'},  {"notitle",     0, 0, 't'},  {"reconnect",   0, 0, 'r'},  {"nxterm",      0, 0, 'l'},  {"transparent", 0, 0, 'T'},  {"create",      0, 0, 'm'},  {"noserver",    0, 0, 'n'},  {"config",      1, 0, 'f'},  {"server",      1, 0, 's'},  {"debug",       1, 0, 'd'},  {"log",         1, 0, 'x'},  {"logall",      1, 0, 'g'},  {"user",        1, 0, 'u'},  {"pass",        1, 0, 'p'},  {"password",    1, 0, 'p'},  {"email",       1, 0, 'e'},  {"upload",      1, 0, 'U'},  {"download",    1, 0, 'D'},  {"incomplete",  1, 0, 'I'},  {"dataport",    1, 0, 'P'},  {"connection",  1, 0, 'C'},  {"maxuploads",  1, 0, 'M'},  {"option",      1, 0, 'o'},  {0, 0, 0, 0}};void phelp(char *nm){  printf("Usage: %s [options]\n", nm);  printf("Options:\n");  printf("-h, --help             - print this help message\n");  printf("-v, --version          - print version info and exit\n");  printf("-b, --build            - build library of shared files to send to server\n");  printf("-B, --build-only       - build library and exit\n");  printf("-N, --nobuild          - do not build library, even if it is out of date\n");  printf("-m, --create           - create new account on server (obsolete)\n");  printf("-r, --reconnect        - keep reconnecting until server connection established\n");  printf("-a, --autorestart      - automatically reconnect when connection to server lost\n");  printf("-q, --daemon           - run without user interface; file sharing only\n");  printf("-t, --notitle          - do not display title bar (fixes messed-up displays)\n");  printf("-l, --nxterm           - try using a terminal which is compatible with most\n"	 "                         systems (fixes some messed-up displays)\n");  printf("-T, --transparent      - use terminal's default background instead of black\n");  printf("-n, --noserver         - start up without connecting to a server\n");  printf("-f, --config fn        - config file to use (default $HOME/"CONFIGFILE")\n");  printf("-x, --log fn           - log all transfers to a specific filename\n");  printf("-g, --logall fn        - log everything to a specific filename\n");  printf("-s, --server sv:port   - select a specific server (multiple -s opts possible)\n");  printf("-d, --debug n          - set debug level\n");  printf("-u, --user str         - specify napster username\n");  printf("-p, --pass str         - specify user's password\n");  printf("-e, --email str        - specify user's email address\n");  printf("-U, --upload dir       - specify upload directory (multiple -U opts possible)\n");  printf("-D, --download dir     - specify download directory\n");  printf("-I, --incomplete dir   - specify directory for incomplete files\n");  printf("-P, --dataport n-m     - specify port(s) to use for incoming upload requests\n");  printf("-C, --connection n     - specify connection speed number (see README)\n");  printf("-M, --maxuploads n     - specify maximum number of simultaneous uploads\n");  printf("-o, --option var=value - set user variable\n");}void pversion() {  printf("nap v"VERSION", a console napster client.\n"	"Written by Kevin Sullivan. Modified by Peter Selinger and others.\n");}void dopts(int argc, char **argv){  int c;  char *p;    /* defaults */  info.name = argv[0];  info.user = NULL;  info.pass = NULL;  info.email = NULL;  info.up = NULL;  info.down = NULL;  info.dataport = NULL;  info.shared_filename = NULL;  info.logallfile = NULL;  info.logfile = NULL;  info.daemon = 0;  info.nxterm = 0;  info.autorestart = 0;  info.serverlist = NULL;  info.build = 0;  info.create = 0;  info.reconnect = 0;  info.noserver = 0;  info.notop = 0;  info.transparent = 0;  info.bandwidthdown = -1;  info.bandwidthup = -1;  info.bandwidthdownconn = -1;  info.bandwidthupconn = -1;  info.sflag = 0;  while ((c = getopt_long(argc, argv, "h?vbBNmrqatlTnf:x:g:s:d:u:p:e:U:D:P:C:M:o:", 			  longopts, NULL)) != -1)  {    switch (c)    {    case 'q':      info.daemon=1;      break;    case 'a':      chset("autorestart", "1");      break;    case 'd':      chset("debug", optarg);      break;    case 'b':      info.build = 1;      break;    case 'B':      info.build = 2;      break;    case 'N':      info.build = -1;      break;    case 'm':      info.create = 1;      break;    case 'r':      info.reconnect = 1;      break;    case 'n':      info.noserver = 1;    case 'f':      chset("configfile", optarg);      break;    case 't':      info.notop = 1;      break;    case 's':      if (info.serverlist == NULL) {	info.serverlist = strdup(optarg);      } else {	info.serverlist = (char *)realloc(info.serverlist, strlen(info.serverlist)+strlen(optarg)+2);	strcat(info.serverlist, ";");	strcat(info.serverlist, optarg);      }      info.sflag = 1;      break;    case 'o':      p = strchr(optarg, '=');      if (!p) {	chset(optarg, "1");      } else {	*p++ = 0;	chset(optarg, p);      }      break;    case 'l':      info.nxterm = 1;      break;    case 'T':      info.transparent = 1;      break;    case 'g':      info.logallfile = strdup(optarg);      break;    case 'x':      info.logfile = strdup(optarg);      break;    case '?':      wp(NULL, "Try --help for more info\n");      exit(1);      break;    case 'h':      phelp(*argv);      exit(0);      break;    case 'v':      pversion();      exit(1);      break;    case 'u':      info.user = strdup(optarg);      break;    case 'p':      info.pass = strdup(optarg);      break;    case 'e':      info.email = strdup(optarg);      break;    case 'U':  /* note there can be several -U options, each adding a dir */      if (!info.up) {	info.up = strdup(optarg);	break;      }      info.up = realloc(info.up, strlen(info.up)+strlen(optarg)+2);      if (info.up) {	strcat(info.up, ";");	strcat(info.up, optarg);      }      break;	       case 'D':      info.down = strdup(optarg);      break;    case 'I':      info.incomplete = strdup(optarg);      break;    case 'P':      info.dataport = strdup(optarg);      break;    case 'C':      chset("connection", optarg);      break;    case 'M':      chset("maxuploads", optarg);      break;    default:      wp(NULL, "Invalid option -- %c\n", c);      exit(1);    }  }  if (optind < argc) {    wp(NULL, "%s: unrecognized argument -- %s\n", *argv, argv[optind]);    wp(NULL, "Try --help for more info\n");    exit(1);  }      return;}/* works like rename(2), except that it can also move a file between   different filesystems. Note that the latter operation is not done   atomically. Returns 0 on success, -1 on error with errno set. */int move_file(const char *oldpath, const char *newpath) {  int r, c;  FILE *f1;  FILE *f2;  struct stat st;  struct utimbuf u;  r = rename(oldpath, newpath);  if (!r)    return(0);    if (errno != EXDEV)    return(r);  /* errno == EXDEV, so we must copy the file */  f1 = fopen(oldpath, "r");  if (!f1) {    return(-1);  }  f2 = fopen(newpath, "w");  if (!f2) {    fclose(f1);    return(-1);  }  for (c=fgetc(f1); c!=EOF; c=fgetc(f1)) {    r = fputc(c, f2);    if (r==EOF) {      fclose(f1);      fclose(f2);      unlink(newpath);      return(-1);    }  }  fclose(f1);  fclose(f2);  /* done copying the file, now attempt to copy its attributes. We     ignore errors during this part. */  r = stat(oldpath, &st);  if (r)     goto remove;  chmod(newpath, st.st_mode);  chown(newpath, st.st_uid, st.st_gid);  u.actime = st.st_atime;  u.modtime = st.st_mtime;  utime(newpath, &u);   remove:  /* now remove the old file */  unlink(oldpath);  return(0);}/* set up the configuration directory. For version 1.4.4-ps9, move old   config files to their new locations. In later versions this extra   step may be omitted. Return 1 if directory was created, else 0.   Exit nap if the directory does not exist but could not be created.  */int setup_configdir(void) {  struct stat st;  char *configdir, *tmp1, *tmp2;  int r;  configdir = home_file(CONFIGDIR);  /* if the config directory already exists, return. In case there is     a file .nap/nap.conf (as in older debian distributions), rename it. */  r = stat(configdir, &st);  if ((r == 0) && S_ISDIR(st.st_mode)) {    tmp1 = home_file(CONFIGDIR"/nap.conf");    tmp2 = home_file(CONFIGFILE);    move_file(tmp1, tmp2);    free(tmp1);    free(tmp2);    free(configdir);    return 0;  }  /* else, set it up */  r = mkdir(configdir, 0700);  if (r==-1) {    wp(NULL, "Could not create the config directory %s: %s\n", configdir, strerror(errno));    exit(1);  }  free(configdir);  wp(NULL, "Created config directory %s\n", configdir);  /* move the most important config files (or rather those with fixed     names) to their new locations.  Ignore errors (which probably     mean some files did not exist). */  tmp1 = home_file(".napconf");  tmp2 = home_file(CONFIGFILE);  move_file(tmp1, tmp2);  free(tmp1);  free(tmp2);  tmp1 = home_file(".nap_shared");  tmp2 = home_file(LIBRARYFILE);  move_file(tmp1, tmp2);  free(tmp1);  free(tmp2);  tmp1 = home_file(".nap_aliases");  tmp2 = home_file(ALIASFILE);  move_file(tmp1, tmp2);  free(tmp1);  free(tmp2);  tmp1 = home_file(".nap_handlers");  tmp2 = home_file(HANDLERFILE);  move_file(tmp1, tmp2);  free(tmp1);  free(tmp2);  return 1;}/* return the next server from the serverlist, or NULL if there are no   more. Start from the beginning of the list if serverlist has   changed since last call, or if NULL was returned by last call */char *next_server(char *serverlist) {  static char *last_serverlist = NULL; /* read-only copy of serverlist */  static char *serverlist_dup = NULL;  /* writable copy of serverlist */  static char *next_tok = NULL;        /* points into serverlist_dup */  char *p;  /* just in case */  if (!serverlist) {    return NULL;  }  if (last_serverlist && strcmp(serverlist,last_serverlist) != 0) {    free(last_serverlist);    last_serverlist = NULL;  }    if (!last_serverlist) {    last_serverlist = strdup(serverlist);    free(serverlist_dup);    serverlist_dup = strdup(serverlist);    next_tok = serverlist_dup;  }  p = strsep(&next_tok, ";");  if (p) {    return p;  } else {    free(serverlist_dup);    serverlist_dup = strdup(serverlist);    next_tok = serverlist_dup;    return NULL;  }}/* return the "connection speed", a number between 0-10. For the most   part, we trust the number given by the user; however, if the user   has put a serious bandwidth limit on uploads, then we do not allow   her to claim she has a high connection speed. Note: this is not   perfect, since the connection speed is only announced to the server   at connect time, and the bandwidth limit might be changed   later. But what can we do? */int connection(void) {  int c;  int limit=0;  c = nvar("connection");  if (c<0 || c>10) {    c = 0;  }    if (info.bandwidthup != 0) {    limit = info.bandwidthup;  }  if (info.bandwidthupconn != 0) {    if (!limit || info.bandwidthupconn < limit)      limit = info.bandwidthupconn;  }  if (limit <= 0)    return c;  while (limit < speeds[c])     c--;  return c;}/* the main procedure: read command line, parse configuration file,   check and create various things and then enter event loop; afterwards    shut down and quit */int main(int argc, char *argv[]){  int s, n, c, r;  char *srv;  char *t = NULL;  FILE *fl;  char *fn;  const char *errmsg;  char *libraryfile, *aliasfile, *handlerfile;  char *ans, *serial;  FILE *nfile;  char *nfilename;  /* set up some signal handlers (more below) */  signal(SIGCHLD, SIG_IGN);  signal(SIGPIPE, SIG_IGN);  /* initialize main screen's internal state */  cbuf[0] = 0;  screen = MAIN_SCREEN;    dopts(argc, argv);    /* create the ~/.nap directory, if it does not already exist. Move     any old config files to their new locations. */  setup_configdir();  /* open log files, if any. Note we do this before reading config file,    so that logging starts early. */  fn = getval("configfile");  if (!fn)    fn = home_file(CONFIGFILE);  else    fn = strdup(fn);

⌨️ 快捷键说明

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