Example #1
0
void
nextconfig (const char *file)
{
#ifndef IPV6
  struct servent *sp;
#endif
  struct servtab *sep, **sepp;
  struct passwd *pwd;
  FILE *fconfig;
  SIGSTATUS sigstatus;

  size_t line = 0;

  fconfig = setconfig (file);
  if (!fconfig)
    {
      syslog (LOG_ERR, "%s: %m", file);
      return;
    }
  while ((sep = getconfigent (fconfig, file, &line)))
    {
      if ((pwd = getpwnam (sep->se_user)) == NULL)
	{
	  syslog (LOG_ERR, "%s/%s: No such user '%s', service ignored",
		  sep->se_service, sep->se_proto, sep->se_user);
	  continue;
	}
      if (ISMUX (sep))
	{
	  sep->se_fd = -1;
	  sep->se_checked = 1;
	  enter (sep);
	}
      else
	expand_enter (sep);
      freeconfig (sep);
    }
  endconfig (fconfig);
  /*
   * Purge anything not looked at above.
   */
  signal_block (&sigstatus);
  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 ("FREE", sep);
      freeconfig (sep);
      free (sep);
    }
  signal_unblock (&sigstatus);
}
Example #2
0
/**
 * \fn int exittimeout()
 * \brief send timeout and exit propely
 */
int
exittimeout ()
{
  clearData ();
  sendTxt ("451 timeout\r\n");
  free_commands ();
  freeconfig ();
  exit (0);
  return 451;
}
Example #3
0
/** 
 * \fn quit(char *c)
 * \brief send goodbye message and close the quit the process
 */
int
quit (char *c)
{
  clearData ();
  sendTxt ("221 Service closing transmission channel\r\n");
  free_commands ();
  freeconfig ();
  freeAllPlugin ();
  exit (0);
  return 221;
}
Example #4
0
/**
 * \fn void exitTalkEarlier()
 * \brief exit when the client don't wait the 220 greeting message
 */
void
exitTalkEarlier ()
{
  sendTxt ("451 you must wait 220 code\r\n");
  if (config->exitTalkEarlier)
    {
      clearData ();
      sendTxt ("451 you must wait 220 code\r\n");
      free_commands ();
      freeconfig ();
      exit (0);
    }
}
Example #5
0
int main(const int argc, const char *const argv[])
{
	printf("running with pid %d\n", getpid());

	const treeplugin tp = {
		.rc = formconfig(argc, argv, 64, 0),
		.extra = NULL,
		.treeroutine = treeroutine,
		.makeargument = makeargument,
		.dropargument = dropargument };

	treespawn(&tp);

	sleep(tp.rc->size);

	freeconfig((runconfig *)tp.rc);
	
	return 0;
}
Example #6
0
struct servtab *
getconfigent (FILE *fconfig, const char *file, size_t *line)
{
  static struct servtab serv;
  struct servtab *sep = &serv;
  int argc = 0;
  size_t i;
  char **argv = NULL;
  char *node, *service;
  static char TCPMUX_TOKEN[] = "tcpmux/";
#define MUX_LEN		(sizeof(TCPMUX_TOKEN)-1)

  if (serv_node)
    return next_node_sep (sep);

  memset ((caddr_t) sep, 0, sizeof *sep);

  while (1)
    {
      argcv_free (argc, argv);
      freeconfig (sep);
      memset ((caddr_t) sep, 0, sizeof *sep);

      do
	{
	  ssize_t n = getline (&linebuf, &linebufsize, fconfig);
	  if (n < 0)
	    return 0;
	  else if (n == 0)
	    continue;

	  if (linebuf[n-1] == '\n')
	    linebuf[n-1] = 0;
	  ++ *line;
	}
      while (*linebuf == '#' || *linebuf == 0);

      if (argcv_get (linebuf, "", &argc, &argv))
	continue;

      if (argc < INETD_FIELDS_MIN)
	{
	  if (argc == 1 && argv[0][strlen (argv[0]) - 1] == ':')
	    {
	      argv[0][strlen (argv[0]) - 1] = 0;
	      free (global_serv_node);
	      if (strcmp (argv[0], "*"))
		global_serv_node = newstr (argv[0]);
	    }
	  else
	    syslog (LOG_ERR, "%s:%lu: not enough fields",
		    file, (unsigned long) *line);
	  continue;
	}

      sep->se_file = file;
      sep->se_line = *line;

      node = argv[INETD_SERVICE];
      service = strchr (node, ':');
      if (!service)
        {
	  if (global_serv_node)
	    {
	      node = global_serv_node;
	      serv_node = newstr (node);
	      serv_node_offset = 0;
	    }
	  else
	      node = NULL;

	  service = argv[INETD_SERVICE];
        }
      else
        {
          *service++ = 0;
          if (strcmp (node, "*") == 0)
            node = NULL;
	  else
	    {
	      serv_node = newstr (node);
	      serv_node_offset = 0;
	    }
        }

      if (strncmp (service, TCPMUX_TOKEN, MUX_LEN) == 0)
	{
	  char *c = service + MUX_LEN;
	  if (*c == '+')
	    {
	      sep->se_type = MUXPLUS_TYPE;
	      c++;
	    }
	  else
	    sep->se_type = MUX_TYPE;
	  sep->se_service = newstr (c);
	}
      else
	{
	  sep->se_service = newstr (service);
	  sep->se_type = NORM_TYPE;
	}

      if (strcmp (argv[INETD_SOCKET], "stream") == 0)
	sep->se_socktype = SOCK_STREAM;
      else if (strcmp (argv[INETD_SOCKET], "dgram") == 0)
	sep->se_socktype = SOCK_DGRAM;
      else if (strcmp (argv[INETD_SOCKET], "rdm") == 0)
	sep->se_socktype = SOCK_RDM;
      else if (strcmp (argv[INETD_SOCKET], "seqpacket") == 0)
	sep->se_socktype = SOCK_SEQPACKET;
      else if (strcmp (argv[INETD_SOCKET], "raw") == 0)
	sep->se_socktype = SOCK_RAW;
      else
	{
	  syslog (LOG_WARNING, "%s:%lu: bad socket type",
		  file, (unsigned long) *line);
	  sep->se_socktype = -1;
	}

      sep->se_proto = newstr (argv[INETD_PROTOCOL]);

#ifdef IPV6
      /* We default to IPv6, in setup() we'll fall back to IPv4 if
         it doesn't work.  */
      sep->se_family = AF_INET6;
      sep->se_v4mapped = 1;

      if ((strncmp (sep->se_proto, "tcp", 3) == 0)
	  || (strncmp (sep->se_proto, "udp", 3) == 0))
	{
	  if (sep->se_proto[3] == '6')
	    {
	      sep->se_family = AF_INET6;
	      sep->se_v4mapped = 0;
	    }
	  else if (sep->se_proto[3] == '4')
	    {
	      sep->se_family = AF_INET;
	    }
	}
#else
      if ((strncmp (sep->se_proto, "tcp6", 4) == 0)
	  || (strncmp (sep->se_proto, "udp6", 4) == 0))
	{
	  syslog (LOG_ERR, "%s:%lu: %s: IPv6 support isn't enabled",
		  file, (unsigned long) *line, sep->se_proto);
	  continue;
	}

      sep->se_family = AF_INET;
#endif
      {
	char *p, *q;

	p = strchr(argv[INETD_WAIT], '.');
	if (p)
	  *p++ = 0;
	if (strcmp (argv[INETD_WAIT], "wait") == 0)
	  sep->se_wait = 1;
	else if (strcmp (argv[INETD_WAIT], "nowait") == 0)
	  sep->se_wait = 0;
	else
	  {
	    syslog (LOG_WARNING, "%s:%lu: bad wait type",
		    file, (unsigned long) *line);
	  }
	if (p)
	  {
	    sep->se_max = strtoul(p, &q, 10);
	    if (*q)
	      syslog (LOG_WARNING, "%s:%lu: invalid number (%s)",
		      file, (unsigned long) *line, p);
	  }
      }

      if (ISMUX (sep))
	{
	  /*
	   * Silently enforce "nowait" for TCPMUX services since
	   * they don't have an assigned port to listen on.
	   */
	  sep->se_wait = 0;

	  if (strncmp (sep->se_proto, "tcp", 3))
	    {
	      syslog (LOG_ERR, "%s:%lu: bad protocol for tcpmux service %s",
		      file, (unsigned long) *line, sep->se_service);
	      continue;
	    }
	  if (sep->se_socktype != SOCK_STREAM)
	    {
	      syslog (LOG_ERR,
		      "%s:%lu: bad socket type for tcpmux service %s",
		      file, (unsigned long) *line, sep->se_service);
	      continue;
	    }
	}

      sep->se_user = newstr (argv[INETD_USER]);
      sep->se_server = newstr (argv[INETD_SERVER_PATH]);
      if (strcmp (sep->se_server, "internal") == 0)
	{
	  sep->se_bi = bi_lookup (sep);
	  if (!sep->se_bi)
	    {
	      syslog (LOG_ERR, "%s:%lu: internal service %s unknown",
		      file, (unsigned long) *line, sep->se_service);
	      continue;
	    }
	  sep->se_wait = sep->se_bi->bi_wait;
	}
      else
	sep->se_bi = NULL;

      sep->se_argc = argc - INETD_FIELDS_MIN + 1;
      sep->se_argv = calloc (sep->se_argc + 1, sizeof sep->se_argv[0]);
      if (!sep->se_argv)
	{
	  syslog (LOG_ERR, "%s:%lu: Out of memory.",
		  file, (unsigned long) *line);
	  exit (-1);
	}

      for (i = 0; i < sep->se_argc; i++)
	{
	  sep->se_argv[i] = argv[INETD_SERVER_ARGS + i];
	  argv[INETD_SERVER_ARGS + i] = 0;
	}
      sep->se_argv[i] = NULL;
      break;
    }
  argcv_free (argc, argv);
  return next_node_sep (sep);
}
Example #7
0
void
fix_tcpmux ()
{
  struct servtab *sep;
  int need_tcpmux = 0;
  int has_tcpmux = 0;

  for (sep = servtab; sep; sep = sep->se_next)
    {
      if (sep->se_checked)
	{
	  if (ISMUX (sep))
	    {
	      if (has_tcpmux)
		return;
	      need_tcpmux = 1;
	    }
	  if (strcmp (sep->se_service, "tcpmux") == 0)
	    {
	      if (need_tcpmux)
		return;
	      has_tcpmux = 1;
	    }
	}
    }
  if (need_tcpmux && !has_tcpmux)
    {
      struct servtab serv;
      memset (&serv, 0, sizeof (serv));

      serv.se_service = newstr ("tcpmux");
      serv.se_socktype = SOCK_STREAM;
      serv.se_proto = newstr ("tcp");
      serv.se_checked = 1;
      serv.se_user = newstr ("root");
      serv.se_bi = bi_lookup (&serv);
      if (!serv.se_bi)
	{
	  /* Should not happen */
	  freeconfig (&serv);
	  if (debug)
	    fprintf (stderr, "INETERNAL ERROR: could not found tcpmux built-in");
	  syslog (LOG_ERR, "INETERNAL ERROR: could not found tcpmux built-in");
	  return;
	}
      serv.se_wait = serv.se_bi->bi_wait;
      serv.se_server = newstr ("internal");
      serv.se_fd = -1;
      serv.se_type = NORM_TYPE;
#ifdef IPV6
      serv.se_family = AF_INET6;
      serv.se_v4mapped = 1;
#else
      serv.se_family = AF_INET;
#endif
      if (debug)
	fprintf (stderr, "inserting default tcpmux entry\n");
      syslog (LOG_INFO, "inserting default tcpmux entry");
      enter (&serv);
    }
}