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

📄 nap.c

📁 P2P NAP的C实现 P2P在网络应用中越来越流行
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Copyright (c) 2000  Kevin Sullivan <nite@gis.net> * * Please refer to the COPYRIGHT file for more information. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE /* needed for stdio.h:vasprintf */#include <stdio.h>#include <time.h>#include <stdarg.h>#include <termios.h>#include <dirent.h>#include <fcntl.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/wait.h>#include <utime.h>#include <ncurses.h>#include <stdlib.h>#include <signal.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/time.h>#include <netdb.h>#include <errno.h>#include "getopt.h"#include "defines.h"#include "codes.h"#include "colors.h"#include "title.h"#include "alias.h"#include "event.h"#include "handlers.h"#include "lists.h"#include "nap.h"#include "scheck.h"#include "winio.h"#include "missing.h"#ifdef MEMWATCH  #include "memwatch.h"#endif/* standard napster servers */extern int ircin;extern int ircsock;extern int ups[], speeds[];extern char cbuf[];extern upload_t *up;extern download_t *down;chans_t *chanl = NULL, *curchan = NULL;hotlist_t *hlist = NULL;info_t info;          /* struct to hold some command line options */int cloaked = 0;      /* whether we are cloaked */int lpbrk=0, noresolv=0, reconnect=0;int ipcs[2];int dresize = 0;void doquit(){  scrollbottom();  if (wchan)  {    dscr(wchan);    drw(wchan);  }  if (ircin)  {    ssock(ircsock, "QUIT :Leaving\n");    close(ircsock);    ircsock = 0;  }  if (nvar_default("savechannels", 0)) {    char *tmp = NULL, *fn;    msprintf(&tmp, CHANNELFILE, info.user);    fn = home_file(tmp);    free(tmp);    if (savechans(chanl, fn)==-1) {      wp(wchan, ""RED"* Could not save channels to %s: %s"WHITE"\n", fn, \	 strerror(errno));    } else {      wp(wchan, "* Saved channels to %s\n", fn);    }    free(fn);  }  /* close incomplete files, remove turds, etc */  while (up)    dupload(up);  while (down)    ddownload(wchan, down);  endwin();  exit(1);}void tresize(int dummy){  dresize = 1;}/* catch interrupt signal, i.e. usually "Control-C". In interactive   mode, quit program only after receiving two interrupts within one   second. Interrupt also causes a "while" loop to be broken - see   dwhile in cmds.c */void sigint(int dummy){  int save_errno = errno;  static time_t cct = 0;  if ((time(NULL)-cct) <= 1)    doquit();    cct = time(NULL);  lpbrk = 1;  errno = save_errno;}/* the following is used as a signal "handler" if we just want the   signal to cause a side effect, such as interrupting sleep(3) */void noop(int dummy){  /* empty */}/* handle the USR1 signal. This should schedule the "reconnect" command. */void sigusr1(int dummy){  reconnect = 1;}  void dochecks(){  if (dresize)  {    dresize = 0;    resize();  }}/* quotes a string so that it is printable. Each call frees the   previously returned value. */char *quote(char *s) {  static char *buf = NULL;  int i, size;  if (buf) {    free(buf);  }  size = strlen(s) * 1.2;  buf = (char *)malloc(size);  for (i=0; *s != 0; s++) {    if (i>size-10) {      size += 100;      buf = (char *)realloc(buf, size);    }    if (32 <= *s && *s < 127) { /* printable ASCII */      buf[i++] = *s;    } else if (*s == '\n') {      i += sprintf(&buf[i], "\\n");    } else if (*s == '\r') {      i += sprintf(&buf[i], "\\r");    } else {      i += sprintf(&buf[i], "\\%03o", (unsigned char)*s);    }  }  buf[i] = 0;  return buf;}/* returns the full path of file fn relative to user's home   directory. Always returns an allocated string. */char *home_file(const char *fn) {  char *home, *res;  int len;  if (fn[0] == '/')         /* absolute filename? */    return strdup(fn);  if (0==strncmp(fn,"~/",2))   /* handle also ~/ syntax - dz */    fn += 2;  home = getenv("HOME");   /* else, try to find home directory */  if (!home)    return strdup(fn);  len = strlen(home);  res = (char *)malloc(len+strlen(fn)+2);  strcpy(res, home);  if (home[len-1] != '/')    strcat(res, "/");  strcat(res, fn);  return res;}/* make a an allocated string from an integer, similar to strdup */char *itoa(int n) {  char buf[20];  sprintf(buf, "%d", n);  return strdup(buf);}/* strip whitespace from both ends of a string, descructively */char *strip(char *s) {  char *p;  if (!s)    return NULL;  while (isspace(*s)) {    s++;  }  p = s+strlen(s);  while (p>s && isspace(p[-1]))    p--;  *p = 0;  return s;}/* read an allocated, stripped line from stream. Return NULL on eof or   error. */char *nap_getline(FILE *f) {  char *buf;  char *res;  int size;     /* current allocated size of buf */  int l;  size = 200;   /* should be large enough to hold an average line from		 * the shared library without having to realloc() the		 * buffer */  buf = (char *)malloc(size);  res = fgets(buf, size, f);  if (!res) {          /* end of file */    free(buf);    return NULL;  }  while (!strchr(buf, '\n')) {    size *= 2;    buf = (char *)realloc(buf, size);    l = strlen(buf);    res = fgets(buf+l, size-l, f);    if (!res)          /* end of file */      break;  }  /* strip whitespace from both ends */  res = strdup(strip(buf));  free(buf);  return res;}/* Read the config file FN. Values that were given on the command line   override those in the config file - don't read them. Note: if user   was specified on the command line, take special care *not* to use   password and email address from config file. FN must be a non-null   filename. Return 0. */int readcfg(char *fn) {  int other_user = 0;  char *user=NULL, *pass=NULL, *email=NULL;  int r;  struct stat st;  char *gfn;  if (getval("user")) { /* user was specified on command line - do not                           use password or email from config file */    other_user = 1;    user = strdup(getval("user"));    pass = getrealval("pass");    if (pass)      pass = strdup(pass);    email = getval("email");    if (email)      email = strdup(email);  }    /* read the config file - but in a wimpy way that does not overwrite     existing values. This is because command line values should have     priority. */  wp(NULL, "Reading user config file %s...\n", fn);  r = loadsets(fn, NULL, 0, 0);  if (r==0) {    /* success */  } else if (r==1) {    wp(NULL, "There were some warnings, please edit your config file.\n");  } else if (errno == ENOENT) {   /* no such file or directory */    wp(NULL, "%s: file not found.\n", fn);  } else {    wp(NULL, "Error loading config file %s: %s\n", fn, strerror(errno));  }  /* read the global config file, if any. Note that this is read     *last*. I.e., the values given there are the *least*     authoritative. */  gfn = getval("globalconfigfile");  if (!gfn) {    gfn = GLOBALCONFIGFILE;  }  if (gfn) {    r = stat(gfn, &st);    if (r==0 && S_ISREG(st.st_mode)) { /* only if file exists and is regular */            wp(NULL, "Reading global config file %s...\n", gfn);      r = loadsets(gfn, NULL, 0, 0);            if (r==0) {	/* success */      } else if (r==1) {	wp(NULL, "There were some warnings, please edit global config file.\n");      } else if (errno == ENOENT) {   /* no such file or directory */	wp(NULL, "%s: file not found.\n", gfn);      } else {	wp(NULL, "Error loading global config file %s: %s\n", gfn, strerror(errno));      }    }  }  /* restore password and email if necessary */  if (other_user) {    chset("user", user);    chset("pass", pass);    chset("email", email);    free(user);    free(pass);    free(email);  }    return 0;}/* Try to guess reasonable defaults for vital configuration variables.   Where appropriate, prompt the user. Return -1 if the user refused   to supply a username or password, else 0. FN must be a non-null   filename for the config file to be created / updated. If FN is   null, nothing will be written to a file. Note: if info.daemon is   set, then we never prompt the user for anything, and supply   defaults as we can. */int set_defaults_interactive(char *fn) {  int changes = 0;  char *ans;  char *user, *pass;  int conn;  int r;  struct stat st;  int userprompt = 0;  ans = NULL;  if (!getval("user")) {    if (!info.daemon) {      userprompt = 1;      wp(NULL, "User: ");      ans = nap_getline(stdin);    }    if (!ans || !*ans) {      wp(NULL, "No user name given\n");      free(ans);      return(-1);    } else {      chset("user", ans);      changes = 1;    }  }  free(ans);  ans = NULL;  user = getval("user");  pass = getrealval("pass"); /* note: getval("pass") does not work - it always				returns "?" */  /* if password not defined, check the variable pass.<user> */  if (!pass || !strcmp(pass, "?")) {    char tmp[10+strlen(user)];    strcpy(tmp, "pass.");    strcat(tmp, user);    pass = getval(tmp);    if (pass) {      chset("pass", pass);    }  }  if (!pass || !strcmp(pass,"?")) {    if (userprompt) {      wp(NULL, "Password for user %s (optional): ", user);      ans = getpass(""); /* note: getpass(3) does not allocate its                            result value, thus we should not free it. */    }    if (ans && *ans) {      chset("pass", ans);    }  }  ans = NULL;    pass = getrealval("pass");  if (!pass || !strcmp(pass, "?")) {    char pw[9];    struct timeval tv;    int i;        gettimeofday(&tv, NULL);    srand(tv.tv_usec + 1000000*tv.tv_sec);    for (i=0; i<8; i++) {      pw[i] = rand() % 26 + 'a';    }    pw[8] = 0;    chset("pass", pw);    wp(NULL, "No password given - using random password\n");  }  /* if email not defined, check the variable email.<user> */  if (!getval("email")) {    char *email;    char tmp[10+strlen(user)];    strcpy(tmp, "email.");    strcat(tmp, user);    email = getval(tmp);    if (email) {      chset("email", email);    }  }  if (!getval("email")) {    if (userprompt) {      wp(NULL, "Email for user %s (optional): ", user);      ans = nap_getline(stdin);    }    if (ans && *ans) {      chset("email", ans);      changes = 1;    }    free(ans);    ans = NULL;  }    if (!getval("email")) {    chset("email", "anon@localhost");    wp(NULL, "No email given - using anon@localhost\n");  }  if (!getval("upload")) {    if (!info.daemon) {      wp(NULL, "Please enter a list of directories with files that you want to share.\n");      wp(NULL, "You can enter several directories, separated by semicolons (';').\n");      wp(NULL, "Upload path: ");      ans = nap_getline(stdin);    }    if (!ans || !*ans) {      wp(NULL, "No upload directories given - unable to share files\n");    } else {      chset("upload", ans);      changes = 1;    }  }  free(ans);  ans = NULL;  if (!getval("download")) {    if (!info.daemon) {      wp(NULL, "Please enter the directory where you want to put downloaded files.\n");      wp(NULL, "Download directory: ");      ans = nap_getline(stdin);    }    if (!ans || !*ans) {      wp(NULL, "No download directory given - will use current working directory\n");    } else {      chset("download", ans);      changes = 1;    }  }  free(ans);  ans = NULL;  if (!getval("incomplete")) {    if (!info.daemon) {      wp(NULL, "Please enter the directory where you want to put incomplete files.\n");      wp(NULL, "Incomplete directory: ");      ans = nap_getline(stdin);    }    if (!ans || !*ans) {      wp(NULL, "No incomplete directory given - will use download directory\n");    } else {      chset("incomplete", ans);      changes = 1;    }  }  free(ans);  ans = NULL;  if (!getval("dataport")) {    if (!info.daemon) {      wp(NULL, "Are you behind a firewall? [y=yes, n=no, u=unsure]: ");      ans = nap_getline(stdin);      if (ans && ans[0]=='y') {	wp(NULL, "Firewalled client - setting dataport to 0\n");	chset("dataport", "0");      } else if (ans && ans[0]=='n') {	wp(NULL, "Using dataport 6699-6799\n");	chset("dataport", "6699-6799");      } else {	wp(NULL, "Okay, I will assume that you are not firewalled. If you\n"	   "find out later that you are, please set your dataport to 0.\n");	wp(NULL, "Using dataport 6699-6799\n");	chset("dataport", "6699-6799");      }    } else {      chset("dataport", "6699-6799");      wp(NULL, "No dataport given - using %s\n", getval("dataport"));    }  }  free(ans);  ans = NULL;  if (!getval("connection")) {    if (!info.daemon) {      wp(NULL, 	 "          Connection | Number\n"	 "          -------------------\n"	 "          Unknown    |  0\n"	 "          14.4       |  1\n"	 "          28.8       |  2\n"	 "          33.6       |  3\n"	 "          56.7       |  4\n"	 "          64K ISDN   |  5\n"	 "          128K ISDN  |  6\n"	 "          Cable      |  7\n"	 "          DSL        |  8\n"	 "          T1         |  9\n"	 "          T3 or >    | 10\n"	 );      wp(NULL, "How fast is your internet connection?\n");      wp(NULL, "Please choose 0--10 from the chart: [4] ");      ans = nap_getline(stdin);    }    if (!ans || !*ans) {      chset("connection", "4");      changes = 1;    } else {      chset("connection", ans);

⌨️ 快捷键说明

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