示例#1
0
void
freeconfig (struct servtab *cp)
{
  free (cp->se_node);
  free (cp->se_service);
  free (cp->se_proto);
  free (cp->se_user);
  free (cp->se_server);
  argcv_free (cp->se_argc, cp->se_argv);
}
示例#2
0
文件: argcv.c 项目: baohaojun/dico
int
argcv_get_np (const char *command, int len,
	      const char *delim, const char *cmnt,
	      int flags,
	      int *pargc, char ***pargv, char **endp)
{
  int i = 0;
  struct argcv_info info;
  int argc;
  char **argv;
  
  if (!delim)
    delim = "";
  if (!cmnt)
    cmnt = "";

  init_argcv_info (&info, flags, len, command, delim, cmnt);

  /* Count number of arguments */
  argc = 0;
  while (argcv_scan (&info) <= len)
    argc++;

  argv = calloc ((argc + 1), sizeof (char *));
  if (argv == NULL)
    return ENOMEM;
  
  i = 0;
  info.save = 0;
  for (i = 0; i < argc; i++)
    {
      int n;
      int unquote;
      
      argcv_scan (&info);

      if ((command[info.start] == '"' || command[info.end] == '\'')
	  && command[info.end] == command[info.start])
	{
	  if (info.start < info.end)
	    {
	      info.start++;
	      info.end--;
	    }
	  unquote = 0;
	}
      else
	unquote = 1;
      
      n = info.end - info.start + 1;
      argv[i] = calloc (n + 1,  sizeof (char));
      if (argv[i] == NULL)
	{
	  argcv_free (i, argv);
	  return ENOMEM;
	}
      if (unquote)
	argcv_unquote_copy (argv[i], &command[info.start], n);
      else
	memcpy (argv[i], &command[info.start], n);
      argv[i][n] = 0;
    }
  argv[i] = NULL;

  *pargc = argc;
  *pargv = argv;
  if (endp)
    *endp = (char*) (command + info.finish_pos);
  return 0;
}
示例#3
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);
}
示例#4
0
struct servtab *
enter (struct servtab *cp)
{
  struct servtab *sep;
  SIGSTATUS sigstatus;
  int i;

  /* Checking/Removing duplicates */
  for (sep = servtab; sep; sep = sep->se_next)
    if (memcmp (&sep->se_ctrladdr, &cp->se_ctrladdr,
		sizeof (sep->se_ctrladdr)) == 0
	&& strcmp (sep->se_service, cp->se_service) == 0
	&& strcmp (sep->se_proto, cp->se_proto) == 0
	&& ISMUX (sep) == ISMUX (cp))
      break;
  if (sep != 0)
    {
      signal_block (&sigstatus);
      /*
       * 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);
      argcv_free (sep->se_argc, sep->se_argv);
      sep->se_argc = cp->se_argc;
      sep->se_argv = cp->se_argv;
      cp->se_argc = 0;
      cp->se_argv = NULL;
      sep->se_checked = 1;
      signal_unblock (&sigstatus);
      if (debug)
	print_service ("REDO", sep);
      return sep;
    }

  if (debug)
    print_service ("ADD ", cp);

  sep = (struct servtab *) malloc (sizeof (*sep));
  if (sep == NULL)
    {
      syslog (LOG_ERR, "Out of memory.");
      exit (-1);
    }
  *sep = *cp;
  dupstr (&sep->se_node);
  dupstr (&sep->se_service);
  dupstr (&sep->se_proto);
  dupstr (&sep->se_user);
  dupstr (&sep->se_server);
  dupmem ((void**)&sep->se_argv, sep->se_argc * sizeof (sep->se_argv[0]));
  for (i = 0; i < sep->se_argc; i++)
    dupstr (&sep->se_argv[i]);

  sep->se_fd = -1;
  signal_block (&sigstatus);
  sep->se_next = servtab;
  servtab = sep;
  signal_unblock (&sigstatus);
  return sep;
}