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

📄 linetd.c

📁 linetd是一个压缩TCP高级服务器。所有的设置值都受控于命令行。与tcp服务器或sinetd类似。
💻 C
📖 第 1 页 / 共 2 页
字号:
  }#ifdef USE_IDSA  complete = 1;  cp[0] = IPPROTO_TCP;  cp[1] = ntohs(addr.sin_port);  ca = ntohl(addr.sin_addr.s_addr);  addrlen = sizeof(struct sockaddr_in);  if (getsockname(nfd, (struct sockaddr *) &addr, &addrlen)) {    complete = 0;  }  sp[0] = IPPROTO_TCP;  sp[1] = ntohs(addr.sin_port);  sa = ntohl(addr.sin_addr.s_addr);  ttl = 0;  len = sizeof(int);  if (getsockopt(nfd, SOL_IP, IP_TTL, (void *) &ttl, &len)) {    complete = 0;  }  if (idsa_set(ic, LINET_CC, LINET_SCHEME, 1, ar, cr, ir,         IDSA_SSM,   IDSA_T_STRING, IDSA_SSM_WSTART,         "ip4src",   IDSA_T_ADDR, &ca,         "portsrc",  IDSA_T_PORT,  cp,         "ip4dst",   IDSA_T_ADDR, &sa,         "portdst",  IDSA_T_PORT,  sp,         "ipttl",    IDSA_T_INT,  &ttl,         "complete", IDSA_T_FLAG, &complete,         "active",   IDSA_T_INT,  &child_count,         NULL) != IDSA_L_ALLOW) {    reason=idsa_reason(ic);    if(reason){      write(nfd,reason,strlen(reason));    }    close(nfd);    return -1;  }#endif  return nfd;}int main(int argc, char **argv){  char *user, *group, *interface, *root, *port, *cmd;  int niceinc;  int nofork;  int timeout;  int instances;  int queue;  int reuse;  int keepalive;  int what;  int value;  int offset;  int i, j;  char c;  int lfd;  int nfd;  struct sigaction sag;  sigset_t sst;  int status;  int hang;  int busy;  int tos;  int ttl;  int sane;#ifdef USE_IDSA  int exitcode;  int killcode;  int flags;  unsigned int arisk, crisk, irisk, risk;#endif  double limit_load = 0.0;  port = NULL;  user = NULL;  group = NULL;  root = NULL;  interface = NULL;  cmd = NULL;  sane = 1;  reuse = 1;  keepalive = 1;  niceinc = 0;  nofork = 0;  timeout = 0;  instances = 0;  queue = 5;  tos = 0;  ttl = 0;  offset = 0;#ifdef USE_IDSA  flags = 0;  arisk = idsa_risk_make(-0.3,0.8);  crisk = IDSA_R_UNKNOWN;  irisk = IDSA_R_PARTIAL;#endif  i = j = 1;  while (i < argc) {    if (argv[i][0] == '-') {      c = argv[i][j];      switch (c) {      case 'c':	printf("(c) 2002 Marc Welz: Licensed under the terms of the GNU General Public License\n");	exit(0);	break;      case 'h':		/* print brief help message */	usage(argv[0]);	exit(0);	break;      case 'v':#ifdef USE_IDSA	printf("linetd %s-i\n", VERSION);#else	printf("linetd %s\n", VERSION);#endif	exit(0);	break;	/* flags */      case 'f':		/* keep in foreground */	nofork = 1;	j++;	break;      case 'a' :        /* disable reuse of address */        j++;	c = argv[i][j];	switch (c) {        case 'r':          reuse = 0;          break;	case 'k':          keepalive = 0;          break;	case '\0':	  fatal_failure(LINET_USAGE, 0, "option -a requires a modifier");	  break;	default:	  fatal_failure(LINET_USAGE, 0, "unknown modifier -a%c", c);	  break;        }	j++;	if (argv[i][j] == '\0') {	  j = 1;	  i++;	}        break;      case 'd' :        /* disable sanity checks */        sane = 0;	j++;        break;	/* strings */      case 'u':      case 'g':      case 'p':      case 'r':      case 'b':	j++;	if (argv[i][j] == '\0') {	  j = 0;	  i++;	}	if (i >= argc) {	  fatal_failure(LINET_USAGE, 0, "option -%c requires a parameter", c);	}	switch (c) {	case 'u':	  user = argv[i] + j;	  break;	case 'g':	  group = argv[i] + j;	  break;	case 'p':        	  port = argv[i] + j;	  break;	case 'r':	  root = argv[i] + j;	  break;	case 'b':	  interface = argv[i] + j;	  break;	}	i++;	j = 1;	break;      case 'l':	j++;	if (argv[i][j] == '\0') {	  j = 0;	  i++;	}	if (i >= argc) {	  fatal_failure(LINET_USAGE, 0, "option -%c requires a parameter", c);	}	if (!isdigit(argv[i][j])) {	  fatal_failure(LINET_USAGE, 0, "option -%c requires a floating point value", c);	}        load_fd = open(LOADAVG, O_RDONLY);        if(load_fd < 0){          fatal_failure(LINET_SYSTEM, errno, "unable to open %s to read load average", LOADAVG);        }	limit_load = atof(argv[i] + j);	i++;	j = 1;	break;      case 'n':      case 'm':      case 'i':      case 'q':      case 't':	j++;	if (argv[i][j] == '\0') {	  j = 0;	  i++;	}	if (i >= argc) {	  fatal_failure(LINET_USAGE, 0, "option -%c requires a parameter", c);	}	if (!isdigit(argv[i][j])) {	  fatal_failure(LINET_USAGE, 0, "option -%c requires a numeric value", c);	}	value = atoi(argv[i] + j);	switch (c) {	case 'n':	  niceinc = value;	  break;	case 'm':	  timeout = value;	  break;	case 'i':	  instances = value;	  break;	case 'q':	  queue = value;	  break;	case 't':	  ttl = value;	  break;	}	i++;	j = 1;	break;      case 'o':        j++;	c = argv[i][j];	switch (c) {        case 'c':          tos = IPTOS_LOWCOST;          break;	case 'd':          tos = IPTOS_LOWDELAY;          break;	case 'r':          tos = IPTOS_RELIABILITY;          break;	case 't':          tos = IPTOS_THROUGHPUT;          break;	case '\0':	  fatal_failure(LINET_USAGE, 0, "option -o requires a modifier");	  break;	default:	  fatal_failure(LINET_USAGE, 0, "unknown modifier -o%c", c);	  break;        }	j++;	if (argv[i][j] == '\0') {	  j = 1;	  i++;	}        break;#ifdef USE_IDSA      case 'k' : /* risk ratings */	j++;	c = argv[i][j];	j++;	if (argv[i][j] == '\0') {	  j = 0;	  i++;	}	if (i >= argc) {	  fatal_failure(LINET_USAGE, 0, "option -k%c requires a parameter", c);	}        risk = idsa_risk_parse(argv[i]+j);	switch (c) {	case 'a':          arisk = risk;          break;	case 'c':          crisk = risk;          break;	case 'i':          irisk = risk;          break;        }	i++;	j = 1;        break;      case 'x':        j++;	c = argv[i][j];	switch (c) {        case 'e':	  flags |= IDSA_F_ENV; /* honour IDSA_SOCKET */          break;	case 'o':	  flags |= IDSA_F_FAILOPEN; /* continue on failure */          break;	case 'u':	  flags |= IDSA_F_UPLOAD; /* allow uploading of rules */          break;	case '\0':	  fatal_failure(LINET_USAGE, 0, "option -x requires a modifier");	  break;	default:	  fatal_failure(LINET_USAGE, 0, "unknown modifier -x%c", c);	  break;        }	j++;	if (argv[i][j] == '\0') {	  j = 1;	  i++;	}        break;#endif      case 's':	j++;	c = argv[i][j];	what = 0;	switch (c) {	case 'c':	  what = RLIMIT_CORE;	  break;	case 'd':	  what = RLIMIT_DATA;	  break;	case 'f':	  what = RLIMIT_FSIZE;	  break;	case 'l':	  what = RLIMIT_MEMLOCK;	  break;	case 'm':	  what = RLIMIT_RSS;	  break;	case 'n':	  what = RLIMIT_NOFILE;	  break;	case 's':	  what = RLIMIT_STACK;	  break;	case 't':	  what = RLIMIT_CPU;	  break;	case 'u':	  what = RLIMIT_NPROC;	  break;	case 'v':	  what = RLIMIT_AS;	  break;	case '\0':	  fatal_failure(LINET_USAGE, 0, "option -s requires a modifier");	  break;	default:	  fatal_failure(LINET_USAGE, 0, "unknown modifier -s%c", c);	  break;	}	j++;	if (argv[i][j] == '\0') {	  j = 0;	  i++;	}	if (i >= argc) {	  fatal_failure(LINET_USAGE, 0, "option -s%c requires a parameter", c);	}	if (!isdigit(argv[i][j])) {	  fatal_failure(LINET_USAGE, 0, "option -s%c requires a numeric value", c);	}	value = atoi(argv[i] + j);        if(resource_count >= LINET_MAXRES){	  fatal_failure(LINET_USAGE, 0, "too many resource restrictions", c);        }        resource_table[resource_count][0]=what;        resource_table[resource_count][1]=value;        resource_count++;	i++;	j = 1;	break;      case '-':	j++;	break;      case '\0':	j = 1;	i++;	break;      default:	fatal_failure(LINET_USAGE, 0, "unknown option -%c", argv[i][j]);	break;      }    } else {      cmd = argv[i];      offset = i + 1;      if (sane) {        if (i + 1 >= argc){          fprintf(stderr, "%s: warning: zeroth argument should be specified\n", argv[0]);          offset = i;        }      }      i = argc;    }  }  if (cmd == NULL) {    fatal_failure(LINET_USAGE, 0, "require a command to run");  }  if (!nofork) {    fork_parent(argv[0]);  }#ifdef USE_IDSA  if (ic == NULL) {    ic = idsa_open(LINETD, NULL, flags);  }  if (ic == NULL) {    fprintf(stderr, "%s: unable to open idsa connection\n", argv[0]);    exit(EX_UNAVAILABLE);  }#endif  sigfillset(&(sag.sa_mask));  sag.sa_flags = 0;  sag.sa_handler = handle_child;  if (sigaction(SIGCHLD, &sag, NULL)) {    fatal_failure(LINET_SYSTEM, errno, "unable to set signal handler");  }  sag.sa_handler = handle_stop;  if (sigaction(SIGTERM, &sag, NULL)) {    fatal_failure(LINET_SYSTEM, errno, "unable to set signal handler");  }  lfd = setup_listener(argv[0], port, interface, queue, ttl, tos, reuse, keepalive);  drop_root(argv[0], user, group, root);  if(sane){    if(access(cmd, X_OK)){      fatal_failure(LINET_SYSTEM, errno, "\"%s\" %s", cmd, (cmd[0]=='/') ? "appears unavailable" : "might need an absolute path");    }  }  if (niceinc) {    nice(niceinc);  }#ifdef USE_IDSA  if(idsa_set(ic, LINET_DR, LINET_SCHEME, 1, IDSA_R_SUCCESS, IDSA_R_UNKNOWN, IDSA_R_UNKNOWN,         IDSA_SSM,  IDSA_T_STRING, IDSA_SSM_SSTART,         "version", IDSA_T_STRING, VERSION,         NULL) != IDSA_L_ALLOW){    fprintf(stderr, "%s: start disallowed\n", LINETD);    return EX_NOPERM;  }#endif  if (!nofork) {    close(STDERR_FILENO);  }  sigemptyset(&sst);  sigaddset(&sst, SIGCHLD);  sigaddset(&sst, SIGTERM);  sigprocmask(SIG_BLOCK, &sst, NULL);	/* disable child signal for everything execpt accept and sleep */  while (run) {#ifdef USE_IDSA    nfd = accept_connection(lfd, arisk, crisk, irisk);#else    nfd = accept_connection(lfd);#endif    if (nfd >= 0) {      run_command(lfd, cmd, &argv[offset], nfd, timeout);    }    do{ /* check children and load */      busy=0;      hang = ((instances > 0) && (child_count >= instances)); /* actually wait for child */      if (zombies || hang) {        if (waitpid(WAIT_ANY, &status, hang ? 0 : WNOHANG) > 0) {	/* collect pids without risk of EINTR */#ifdef USE_IDSA          /* in theory this should parse signals and exit codes. Eg SIG{SEGV,BUS} == ES_INTERNAL etc */          if (WIFEXITED(status)) {            exitcode = WEXITSTATUS(status);            if (exitcode == 0) {              idsa_set(ic, LINET_JD, LINET_SCHEME, 0, IDSA_R_NONE, IDSA_R_UNKNOWN, IDSA_R_UNKNOWN,                   IDSA_SSM, IDSA_T_STRING, IDSA_SSM_WSTOP,                   NULL);            } else {              idsa_set(ic, LINET_JE, LINET_SCHEME, 0, IDSA_R_PARTIAL, IDSA_R_UNKNOWN, IDSA_R_PARTIAL,                   IDSA_SSM, IDSA_T_STRING, IDSA_SSM_WFAIL,                   IDSA_ES,  IDSA_T_STRING, IDSA_ES_OTHER,                   "exit",   IDSA_T_INT, &exitcode,                   NULL);            }          } else if (WIFSIGNALED(status)) {            killcode = WTERMSIG(status);            idsa_set(ic, LINET_JS, LINET_SCHEME, 0, IDSA_R_PARTIAL, IDSA_R_UNKNOWN, IDSA_R_PARTIAL,                IDSA_SSM, IDSA_T_STRING, IDSA_SSM_WFAIL,                 IDSA_ES,  IDSA_T_STRING, IDSA_ES_OTHER,                 "signal", IDSA_T_INT, &killcode,                NULL);          }#endif          child_count--;          busy = ! hang;         } else { /* nothing more to collect */          zombies = 0;        }      }      if((load_fd >= 0) && (zombies == 0)){ /* if zombies then loop will run again, defer load check */        if(get_load() > limit_load){ /* go to sleep if overloaded */          sigprocmask(SIG_UNBLOCK, &sst, NULL);	/* enable child|term signal */          sleep(LINET_SLEEP);          sigprocmask(SIG_BLOCK, &sst, NULL);	/* disable child|term signal */          busy=run;        }      }    } while (busy); /* end of child and delay loop */  } /* end of main loop */  if(lfd>=0){    close(lfd);  }  if(load_fd>=0){    close(load_fd);  }#ifdef USE_IDSA  idsa_set(ic, LINET_DE, LINET_SCHEME, 0, IDSA_R_TOTAL, IDSA_R_NONE, IDSA_R_UNKNOWN,       IDSA_SSM,  IDSA_T_STRING, IDSA_SSM_SSTOP,       "version", IDSA_T_STRING, VERSION,       NULL);  idsa_close(ic);#endif  return 0;}

⌨️ 快捷键说明

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