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

📄 inetd.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			    timingout = 1;			    alarm (RETRYTIME);			  }			continue;		      }		  }		pid = fork ();	      }	    if (pid < 0)	      {		syslog (LOG_ERR, "fork: %m");		if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)		  close (ctrl);#ifdef HAVE_SIGACTION		{		  sigset_t empty;		  sigemptyset (&empty);		  sigprocmask (SIG_SETMASK, &empty, 0);		}#else		sigsetmask (0L);#endif		sleep (1);		continue;	      }	    if (pid && sep->se_wait)	      {		sep->se_wait = pid;		if (sep->se_fd >= 0)		  {		    FD_CLR (sep->se_fd, &allsock);		    nsock--;		  }	      }#ifdef HAVE_SIGACTION	    {	      sigset_t empty;	      sigemptyset (&empty);	      sigprocmask (SIG_SETMASK, &empty, 0);	    }#else	    sigsetmask (0L);#endif	    if (pid == 0)	      {		if (debug && dofork)		  setsid ();		if (dofork)		  {		    int sock;		    if (debug)		      fprintf (stderr, "+ Closing from %d\n", maxsock);		    for (sock = maxsock; sock > 2; sock--)		      if (sock != ctrl)			close (sock);		  }		run_service (ctrl, sep);	      }	    if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)	      close (ctrl);	  }    }}voidrun_service (int ctrl, struct servtab *sep){  struct passwd *pwd;  char buf[50];  if (sep->se_bi)    {      (*sep->se_bi->bi_fn) (ctrl, sep);    }  else    {      if (debug)	fprintf (stderr, "%d execl %s\n", getpid (), sep->se_server);      dup2 (ctrl, 0);      close (ctrl);      dup2 (0, 1);      dup2 (0, 2);      if ((pwd = getpwnam (sep->se_user)) == NULL)	{	  syslog (LOG_ERR, "%s/%s: %s: No such user",		  sep->se_service, sep->se_proto, sep->se_user);	  if (sep->se_socktype != SOCK_STREAM)	    recv (0, buf, sizeof buf, 0);	  _exit (1);	}      if (pwd->pw_uid)	{	  if (setgid (pwd->pw_gid) < 0)	    {	      syslog (LOG_ERR, "%s: can't set gid %d: %m",		      sep->se_service, pwd->pw_gid);	      _exit (1);	    }#ifdef HAVE_INITGROUPS	  (void) initgroups (pwd->pw_name, pwd->pw_gid);#endif	  if (setuid (pwd->pw_uid) < 0)	    {	      syslog (LOG_ERR, "%s: can't set uid %d: %m",		      sep->se_service, pwd->pw_uid);	      _exit (1);	    }	}      execv (sep->se_server, sep->se_argv);      if (sep->se_socktype != SOCK_STREAM)	recv (0, buf, sizeof buf, 0);      syslog (LOG_ERR, "cannot execute %s: %m", sep->se_server);      _exit (1);    }}voidreapchild (int signo){  int status;  pid_t pid;  struct servtab *sep;  (void)signo; /* shutup gcc */  for (;;)    {#ifdef HAVE_WAIT3      pid = wait3 (&status, WNOHANG, (struct rusage *)0);#else      pid = wait (&status);#endif      if (pid <= 0)	break;      if (debug)	fprintf (stderr, "%d reaped, status %#x\n", pid, status);      for (sep = servtab; sep; sep = sep->se_next)	if (sep->se_wait == pid)	  {	    if (status)	      syslog (LOG_WARNING, "%s: exit status 0x%x",		      sep->se_server, status);	    if (debug)	      fprintf (stderr, "restored %s, fd %d\n",		       sep->se_service, sep->se_fd);	    FD_SET (sep->se_fd, &allsock);	    nsock++;	    sep->se_wait = 1;	  }    }}voidconfig (int signo){  int i;  struct stat stats;  struct servtab *sep;  (void)signo; /* Shutup gcc.  */  for (sep = servtab; sep; sep = sep->se_next)    sep->se_checked = 0;  for (i = 0; config_files[i]; i++)    {      struct stat statbuf;      if (stat (config_files[i], &statbuf) == 0)	{	  if (S_ISDIR (statbuf.st_mode))	    {	      DIR *dirp = opendir (config_files[i]);	      if (dirp)		{		  struct dirent *dp;		  while ((dp = readdir (dirp)) != NULL)		    {		      char *path = calloc (strlen (config_files[i])					   + strlen (dp->d_name) + 2, 1);		      if (path)			{			  sprintf (path,"%s/%s", config_files[i], dp->d_name);			  if (stat (path, &stats) == 0			      && S_ISREG(stats.st_mode))			    {			      nextconfig (path);			    }			  free (path);			}		    }		  closedir (dirp);		}	    }	  else if (S_ISREG (statbuf.st_mode))	    {	      nextconfig (config_files[i]);	    }	}      else	{	  if (signo == 0)	    fprintf (stderr, "inetd: %s, %s\n",		     config_files[i], strerror(errno));	  else	    syslog (LOG_ERR, "%s: %m", config_files[i]);	}    }}voidnextconfig (const char *file){  struct servtab *sep, *cp, **sepp;  struct passwd *pwd;  FILE * fconfig;#ifdef HAVE_SIGACTION  sigset_t sigs, osigs;#else  long omask;#endif  fconfig = setconfig (file);  if (!fconfig)    {      syslog (LOG_ERR, "%s: %m", file);      return;    }  while ((cp = getconfigent (fconfig, file)))    {      if ((pwd = getpwnam (cp->se_user)) == NULL)	{	  syslog(LOG_ERR, "%s/%s: No such user '%s', service ignored",		 cp->se_service, cp->se_proto, cp->se_user);	  continue;	}      /* Checking/Removing duplicates */      for (sep = servtab; sep; sep = sep->se_next)	if (strcmp (sep->se_service, cp->se_service) == 0	    && strcmp (sep->se_proto, cp->se_proto) == 0	    && ISMUX(sep) == ISMUX (cp))	  break;      if (sep != 0)	{	  int i;#ifdef HAVE_SIGACTION	  sigemptyset (&sigs);	  sigaddset (&sigs, SIGCHLD);	  sigaddset (&sigs, SIGHUP);	  sigaddset (&sigs, SIGALRM);	  sigprocmask (SIG_BLOCK, &sigs, &osigs);#else	  omask = sigblock (SIGBLOCK);#endif	  /*	   * sep->se_wait may be holding the pid of a daemon	   * that we're waiting for.  If so, don't overwrite	   * it unless the config file explicitly says don't	   * wait.	   */	  if (cp->se_bi == 0	      && (sep->se_wait == 1 || cp->se_wait == 0))	    sep->se_wait = cp->se_wait;#define SWAP(a, b) { char *c = a; a = b; b = c; }	  if (cp->se_user)	    SWAP(sep->se_user, cp->se_user);	  if (cp->se_server)	    SWAP(sep->se_server, cp->se_server);	  for (i = 0; i < MAXARGV; i++)	    SWAP(sep->se_argv[i], cp->se_argv[i]);#ifdef HAVE_SIGACTION	  sigprocmask (SIG_SETMASK, &osigs, 0);#else	  sigsetmask (omask);#endif	  freeconfig (cp);	  if (debug)	    print_service (file, "REDO", sep);	}      else	{	  sep = enter (cp);	  if (debug)	    print_service (file, "ADD ", sep);	}      sep->se_checked = 1;      if (ISMUX (sep))	{	  sep->se_fd = -1;	  continue;	}      sp = getservbyname (sep->se_service, sep->se_proto);      if (sp == 0)	{	  syslog (LOG_ERR, "%s/%s: unknown service",		  sep->se_service, sep->se_proto);	  sep->se_checked = 0;	  continue;	}      if (sp->s_port != sep->se_ctrladdr.sin_port)	{	  sep->se_ctrladdr.sin_family = AF_INET;	  sep->se_ctrladdr.sin_port = sp->s_port;	  if (sep->se_fd >= 0)	    close_sep (sep);	}      if (sep->se_fd == -1)	setup (sep);    }  endconfig (fconfig);  /*   * Purge anything not looked at above.   */#ifdef HAVE_SIGACTION  sigemptyset (&sigs);  sigaddset (&sigs, SIGCHLD);  sigaddset (&sigs, SIGHUP);  sigaddset (&sigs, SIGALRM);  sigprocmask (SIG_BLOCK, &sigs, &osigs);#else  omask = sigblock (SIGBLOCK);#endif  sepp = &servtab;  while ((sep = *sepp))    {      if (sep->se_checked)	{	  sepp = &sep->se_next;	  continue;	}      *sepp = sep->se_next;      if (sep->se_fd >= 0)	close_sep (sep);      if (debug)	print_service (file, "FREE", sep);      freeconfig (sep);      free ((char *)sep);    }#ifdef HAVE_SIGACTION  sigprocmask (SIG_SETMASK, &osigs, 0);#else  (void) sigsetmask (omask);#endif}voidretry (int signo){  struct servtab *sep;  (void)signo; /* shutup gcc */  timingout = 0;  for (sep = servtab; sep; sep = sep->se_next)    if (sep->se_fd == -1 && !ISMUX (sep))      setup (sep);}voidsetup (struct servtab *sep){  int on = 1;  if ((sep->se_fd = socket (AF_INET, sep->se_socktype, 0)) < 0)    {      if (debug)	fprintf (stderr, "socket failed on %s/%s: %s\n",		 sep->se_service, sep->se_proto, strerror (errno));      syslog(LOG_ERR, "%s/%s: socket: %m", sep->se_service, sep->se_proto);      return;    }#define	turnon(fd, opt) \setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))  if (strcmp (sep->se_proto, "tcp") == 0 && (options & SO_DEBUG)      && turnon(sep->se_fd, SO_DEBUG) < 0)    syslog (LOG_ERR, "setsockopt (SO_DEBUG): %m");  if (turnon (sep->se_fd, SO_REUSEADDR) < 0)    syslog (LOG_ERR, "setsockopt (SO_REUSEADDR): %m");#undef turnon  if (bind (sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,	    sizeof (sep->se_ctrladdr)) < 0)    {      if (debug)	fprintf (stderr, "bind failed on %s/%s: %s\n",		 sep->se_service, sep->se_proto, strerror (errno));      syslog(LOG_ERR, "%s/%s: bind: %m", sep->se_service, sep->se_proto);      (void) close (sep->se_fd);      sep->se_fd = -1;      if (!timingout)	{	  timingout = 1;	  alarm (RETRYTIME);	}      return;    }  if (sep->se_socktype == SOCK_STREAM)    listen (sep->se_fd, 10);  FD_SET (sep->se_fd, &allsock);  nsock++;  if (sep->se_fd > maxsock)    maxsock = sep->se_fd;  if (debug)    {      fprintf(stderr, "registered %s on %d\n", sep->se_server, sep->se_fd);    }}/* * Finish with a service and its socket. */voidclose_sep (struct servtab *sep){  if (sep->se_fd >= 0)    {      nsock--;      FD_CLR (sep->se_fd, &allsock);      (void) close (sep->se_fd);      sep->se_fd = -1;    }  sep->se_count = 0;  /*   * Don't keep the pid of this running deamon: when reapchild()   * reaps this pid, it would erroneously increment nsock.   */  if (sep->se_wait > 1)    sep->se_wait = 1;}struct servtab *enter (struct servtab *cp){  struct servtab *sep;#ifdef HAVE_SIGACTION  sigset_t sigs, osigs;#else  long omask;#endif  sep = (struct servtab *)malloc (sizeof (*sep));  if (sep == (struct servtab *)0)    {      syslog (LOG_ERR, "Out of memory.");      exit (-1);    }  *sep = *cp;  sep->se_fd = -1;#ifdef HAVE_SIGACTION  sigemptyset (&sigs);  sigaddset (&sigs, SIGCHLD);  sigaddset (&sigs, SIGHUP);  sigaddset (&sigs, SIGALRM);  sigprocmask (SIG_BLOCK, &sigs, &osigs);#else  omask = sigblock (SIGBLOCK);#endif  sep->se_next = servtab;  servtab = sep;#ifdef HAVE_SIGACTION  sigprocmask (SIG_SETMASK, &osigs, 0);#else  sigsetmask (omask);#endif  return sep;}struct	servtab serv;#ifdef LINE_MAXchar	line[LINE_MAX];#elsechar 	line[2048];#endifFILE *setconfig (const char *file){  return fopen (file, "r");}voidendconfig (FILE *fconfig){  if (fconfig)    {      (void) fclose (fconfig);    }}struct servtab *getconfigent (FILE *fconfig, const char *file){  struct servtab *sep = &serv;  int argc;  char *cp, *arg;  static char TCPMUX_TOKEN[] = "tcpmux/";#define MUX_LEN		(sizeof(TCPMUX_TOKEN)-1)more:  while ((cp = nextline (fconfig)) && (*cp == '#' || *cp == '\0'))    ;  if (cp == NULL)    return ((struct servtab *)0);  /*   * clear the static buffer, since some fields (se_ctrladdr,   * for example) don't get initialized here.   */  memset ((caddr_t)sep, 0, sizeof *sep);  arg = skip (&cp, fconfig);  if (cp == NULL)    {      /* got an empty line containing just blanks/tabs. */      goto more;    }  if (strncmp (arg, TCPMUX_TOKEN, MUX_LEN) == 0)    {      char *c = arg + MUX_LEN;      if (*c == '+')	{	  sep->se_type = MUXPLUS_TYPE;	  c++;	}

⌨️ 快捷键说明

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