Пример #1
0
void
register_sasl()
{
  int rc;
  char *listmech;
  struct wordsplit ws;
  
  if (!sasl_enable || init_sasl_0())
      return;
  rc =  gsasl_server_mechlist(ctx, &listmech);
  if (rc != GSASL_OK) {
      dico_log(L_ERR, 0, _("cannot get list of available SASL mechanisms: "
			   "%s"),
	       gsasl_strerror (rc));
      return;
  }

  if (wordsplit(listmech, &ws,
		WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS) == 0) {
      int i;
      for (i = 0; i < ws.ws_wordc; i++) {
	  if (!disabled_mechanism_p(ws.ws_wordv[i])) {
	      char *name = xdico_sasl_mech_to_capa(ws.ws_wordv[i]);
	      dicod_capa_register(name, NULL, init_sasl_1, NULL);
	      dicod_capa_add(name);
	  }
      }
      wordsplit_free(&ws);
  }
  free(listmech);
}
Пример #2
0
static int
split_cfg_path(const char *path, int *pargc, char ***pargv,
	       grecs_value_t ***pvalv)
{
	int argc;
	char **argv;
	char *delim = ".";
	char static_delim[2] = { 0, 0 };
  
	if (path[0] == '\\') {
		argv = calloc(2, sizeof (*argv));
		if (!argv)
			return WRDSE_NOSPACE;
		argv[0] = strdup(path + 1);
		if (!argv[0]) {
			free(argv);
			return WRDSE_NOSPACE;
		}
		argv[1] = NULL;
		argc = 1;
	} else {
		int rc;
		struct wordsplit ws;
		
		if (strchr("./:;,^~", path[0])) {
			delim = static_delim;
			delim[0] = path[0];
			path++;
		}
		ws.ws_delim = delim;
      
		rc = wordsplit(path, &ws,
			       WRDSF_DELIM | WRDSF_DEFFLAGS);
		if (rc)
			return rc;
		argc = ws.ws_wordc;
		argv = ws.ws_wordv;
		ws.ws_wordc = 0;
		ws.ws_wordv = NULL;
		wordsplit_free(&ws);
	}

	*pargv = argv;
	*pargc = argc;
	if (pvalv) {
		int i;
		grecs_value_t **valv;
		
		valv = grecs_calloc(argc, sizeof(valv[0]));
		for (i = 0; i < argc; i++) {
			char *p = strchr(argv[i], '=');
			if (p) {
				*p++ = 0;
				valv[i] = parse_label(p);
			}
		}
		*pvalv = valv;
	}
	return 0;
}
Пример #3
0
char *
_dico_ldap_expand_user(const char *query, const char *user)
{
    struct wordsplit ws;
    const char *env[3];
    char *res;
    
    env[0] = "user";
    env[1] = user;
    env[2] = NULL;

    ws.ws_env = env;
    if (wordsplit(query, &ws,
		  WRDSF_NOSPLIT | WRDSF_NOCMD |
		  WRDSF_ENV | WRDSF_ENV_KV)) {
	dico_log(L_ERR, 0, _("cannot expand query `%s': %s"), query,
		 wordsplit_strerror(&ws));
	return NULL;
    }

    res = ws.ws_wordv[0];
    ws.ws_wordv[0] = NULL;
    wordsplit_free(&ws);
    return res;
}    
Пример #4
0
static int
db_open(void **phandle, dico_url_t url, const char *options)
{
    struct _dico_ldap_handle hstr, *handle;
    int rc;
    long debug = 0;
    
    struct dico_option option[] = {
	{ DICO_OPTSTR(base), dico_opt_string, &hstr.base },
	{ DICO_OPTSTR(binddn), dico_opt_string, &hstr.binddn },
	{ DICO_OPTSTR(passwd), dico_opt_string, &hstr.passwd },
	{ DICO_OPTSTR(tls), dico_opt_bool, &hstr.tls },
	{ DICO_OPTSTR(debug), dico_opt_long, &debug },
	{ DICO_OPTSTR(user-filter), dico_opt_string, &hstr.user_filter },
	{ DICO_OPTSTR(group-filter), dico_opt_string, &hstr.group_filter },
	{ NULL }
    };

    memset(&hstr, 0, sizeof(hstr));
    if (options) {
	struct wordsplit ws;

	if (wordsplit(options, &ws, WRDSF_DEFFLAGS)) {
	    dico_log(L_ERR, 0, _("cannot parse options `%s': %s"), options,
		     wordsplit_strerror(&ws));
	    return 1;
	}

	rc = dico_parseopt(option, ws.ws_wordc, ws.ws_wordv,
			   DICO_PARSEOPT_PARSE_ARGV0, NULL);
	wordsplit_free(&ws);
	if (rc)
	    return 1;
	hstr.debug = debug;
    }
    hstr.url = url->string;
    
    handle = malloc(sizeof(*handle));
    if (!handle) {
	dico_log(L_ERR, errno, _("cannot allocate handle"));
	return 1;
    }
    *handle = hstr;
    
    rc = _dico_conn_setup(handle) ||
	 _dico_ldap_bind(handle);
    if (rc) {
	free_ldap_handle(handle);
    } else {
	*phandle = handle;
    }
    return rc;
}
Пример #5
0
static struct grecs_value *
parse_label(const char *str)
{
	struct grecs_value *val = NULL;
	size_t i;
	struct wordsplit ws;
	size_t len = strlen (str);
  
	if (len > 1 && str[0] == '(' && str[len-1] == ')') {
		struct grecs_list *lst;
      
		ws.ws_delim = ",";
		if (wordsplit_len (str + 1, len - 2, &ws,
				      WRDSF_DEFFLAGS|WRDSF_DELIM|
				      WRDSF_WS)) {
			return NULL;
		}

		lst = grecs_value_list_create();
		for (i = 0; i < ws.ws_wordc; i++) {
			struct grecs_value *p = grecs_zalloc(sizeof(*p));
			p->type = GRECS_TYPE_STRING;
			p->v.string = ws.ws_wordv[i];
			grecs_list_append(lst, p);
		}
		val = grecs_malloc(sizeof(*val));
		val->type = GRECS_TYPE_LIST;
		val->v.list = lst;
	} else {      
		if (wordsplit(str, &ws, WRDSF_DEFFLAGS))
			return NULL;
		val = grecs_zalloc(sizeof(*val));
		if (ws.ws_wordc == 1) {
			val->type = GRECS_TYPE_STRING;
			val->v.string = ws.ws_wordv[0];
		} else {
			val->type = GRECS_TYPE_ARRAY;
			val->v.arg.c = ws.ws_wordc;
			val->v.arg.v = grecs_calloc(ws.ws_wordc,
						    sizeof(val->v.arg.v[0]));
			for (i = 0; i < ws.ws_wordc; i++) {
				val->v.arg.v[i] =
					grecs_zalloc(sizeof(*val->v.arg.v[0]));
				val->v.arg.v[i]->type = GRECS_TYPE_STRING;
				val->v.arg.v[i]->v.string = ws.ws_wordv[i];
			}
		}
	}
	ws.ws_wordc = 0;
	wordsplit_free(&ws);
	return val;
}
Пример #6
0
static void
cvs_addfn (struct exclude *ex, char const *pattern, int options, void *data)
{
  struct wordsplit ws;
  size_t i;

  if (wordsplit (pattern, &ws,
		 WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS))
    return;
  for (i = 0; i < ws.ws_wordc; i++)
    add_exclude (ex, ws.ws_wordv[i], options);
  wordsplit_free (&ws);
}
Пример #7
0
static int
_wsplt_nomem (struct wordsplit *wsp)
{
  errno = ENOMEM;
  wsp->ws_errno = WRDSE_NOSPACE;
  if (wsp->ws_flags & WRDSF_ENOMEMABRT)
    wsp->ws_alloc_die (wsp);
  if (wsp->ws_flags & WRDSF_SHOWERR)
    wordsplit_perror (wsp);
  if (!(wsp->ws_flags & WRDSF_REUSE))
    wordsplit_free (wsp);
  wordsplit_free_nodes (wsp);
  return wsp->ws_errno;
}
Пример #8
0
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
	struct wordsplit_node **ptail, const char **pend, int flg)
{
  size_t i = 0;
  const char *defstr = NULL;
  const char *value;
  const char *vptr;
  struct wordsplit_node *newnode;
  const char *start = str - 1;

  if (ISALPHA (str[0]) || str[0] == '_')
    {
      for (i = 1; i < len; i++)
	if (!(ISALNUM (str[i]) || str[i] == '_'))
	  break;
      *pend = str + i - 1;
    }
  else if (str[0] == '{')
    {
      str++;
      len--;
      for (i = 1; i < len; i++)
	if (str[i] == '}' || str[i] == ':')
	  break;
      if (str[i] == ':')
	{
	  size_t j;

	  defstr = str + i + 1;
	  if (find_closing_cbrace (str, i + 1, len, &j))
	    {
	      wsp->ws_errno = WRDSE_CBRACE;
	      return 1;
	    }
	  *pend = str + j;
	}
      else if (str[i] == '}')
	{
	  defstr = NULL;
	  *pend = str + i;
	}
      else
	{
	  wsp->ws_errno = WRDSE_CBRACE;
	  return 1;
	}
    }
  else
    {
      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_WORD | flg;
      newnode->v.word = malloc (3);
      if (!newnode->v.word)
	return _wsplt_nomem (wsp);
      newnode->v.word[0] = '$';
      newnode->v.word[1] = str[0];
      newnode->v.word[2] = 0;
      *pend = str;
      return 0;
    }

  /* Actually expand the variable */
  /* str - start of the variable name
     i   - its length
     defstr - default replacement str */

  vptr = wordsplit_find_env (wsp, str, i);
  if (vptr)
    {
      value = strdup (vptr);
      if (!value)
	return _wsplt_nomem (wsp);
    }
  else if (wsp->ws_flags & WRDSF_GETVAR)
    value = wsp->ws_getvar (str, i, wsp->ws_closure);
  else if (wsp->ws_flags & WRDSF_UNDEF)
    {
      wsp->ws_errno = WRDSE_UNDEF;
      if (wsp->ws_flags & WRDSF_SHOWERR)
	wordsplit_perror (wsp);
      return 1;
    }
  else
    {
      if (wsp->ws_flags & WRDSF_KEEPUNDEF)
	value = NULL;
      else
	value = "";
    }

  /* FIXME: handle defstr */
  (void) defstr;

  if (value)
    {
      if (flg & _WSNF_QUOTE)
	{
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
	  newnode->v.word = strdup (value);
	  if (!newnode->v.word)
	    return _wsplt_nomem (wsp);
	}
      else if (*value == 0)
	{
	  /* Empty string is a special case */
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_NULL;
	}
      else
	{
	  struct wordsplit ws;
	  int i;

	  ws.ws_delim = wsp->ws_delim;
	  if (wordsplit (value, &ws,
			 WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS))
	    {
	      wordsplit_free (&ws);
	      return 1;
	    }
	  for (i = 0; i < ws.ws_wordc; i++)
	    {
	      if (wsnode_new (wsp, &newnode))
		return 1;
	      wsnode_insert (wsp, newnode, *ptail, 0);
	      *ptail = newnode;
	      newnode->flags = _WSNF_WORD |
		_WSNF_NOEXPAND |
		(i + 1 < ws.ws_wordc ? (flg & ~_WSNF_JOIN) : flg);
	      newnode->v.word = strdup (ws.ws_wordv[i]);
	      if (!newnode->v.word)
		return _wsplt_nomem (wsp);
	    }
	  wordsplit_free (&ws);
	}
    }
  else if (wsp->ws_flags & WRDSF_KEEPUNDEF)
    {
      size_t size = *pend - start + 1;

      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
      newnode->v.word = malloc (size + 1);
      if (!newnode->v.word)
	return _wsplt_nomem (wsp);
      memcpy (newnode->v.word, start, size);
      newnode->v.word[size] = 0;
    }
  else
    {
      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_NULL;
    }
  return 0;
}
Пример #9
0
static int
format_checkpoint_string (FILE *fp, size_t len,
			  const char *input, bool do_write,
			  unsigned cpn)
{
  const char *opstr = do_write ? gettext ("write") : gettext ("read");
  char uintbuf[UINTMAX_STRSIZE_BOUND];
  char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
  const char *ip;

  static char *argbuf = NULL;
  static size_t arglen = 0;
  char *arg = NULL;

  if (!input)
    {
      if (do_write)
	/* TRANSLATORS: This is a "checkpoint of write operation",
	 *not* "Writing a checkpoint".
	 E.g. in Spanish "Punto de comprobaci@'on de escritura",
	 *not* "Escribiendo un punto de comprobaci@'on" */
	input = gettext ("Write checkpoint %u");
      else
	/* TRANSLATORS: This is a "checkpoint of read operation",
	 *not* "Reading a checkpoint".
	 E.g. in Spanish "Punto de comprobaci@'on de lectura",
	 *not* "Leyendo un punto de comprobaci@'on" */
	input = gettext ("Read checkpoint %u");
    }

  for (ip = input; *ip; ip++)
    {
      if (*ip == '%')
	{
	  if (*++ip == '{')
	    {
	      arg = getarg (ip, &ip, &argbuf, &arglen);
	      if (!arg)
		{
		  fputc ('%', fp);
		  fputc (*ip, fp);
		  len += 2;
		  continue;
		}
	    }
	  switch (*ip)
	    {
	    case 'c':
	      len += format_checkpoint_string (fp, len, def_format, do_write,
					       cpn);
	      break;

	    case 'u':
	      fputs (cps, fp);
	      len += strlen (cps);
	      break;

	    case 's':
	      fputs (opstr, fp);
	      len += strlen (opstr);
	      break;

	    case 'd':
	      len += fprintf (fp, "%.0f", compute_duration ());
	      break;

	    case 'T':
	      {
		const char **fmt = checkpoint_total_format, *fmtbuf[3];
		struct wordsplit ws;
		compute_duration ();

		if (arg)
		  {
		    ws.ws_delim = ",";
		    if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD |
				           WRDSF_QUOTE | WRDSF_DELIM))
		      ERROR ((0, 0, _("cannot split string '%s': %s"),
			      arg, wordsplit_strerror (&ws)));
		    else
		      {
			int i;

			for (i = 0; i < ws.ws_wordc; i++)
			  fmtbuf[i] = ws.ws_wordv[i];
			for (; i < 3; i++)
			  fmtbuf[i] = NULL;
			fmt = fmtbuf;
		      }
		  }
		len += format_total_stats (fp, fmt, ',', 0);
		if (arg)
		  wordsplit_free (&ws);
	      }
	      break;

	    case 't':
	      {
		struct timeval tv;
		struct tm *tm;
		const char *fmt = arg ? arg : "%c";

		gettimeofday (&tv, NULL);
		tm = localtime (&tv.tv_sec);
		len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000);
	      }
	      break;

	    case '*':
	      {
		long w = arg ? strtol (arg, NULL, 10) : getwidth (fp);
		for (; w > len; len++)
		  fputc (' ', fp);
	      }
	      break;

	    default:
	      fputc ('%', fp);
	      fputc (*ip, fp);
	      len += 2;
	      break;
	    }
	  arg = NULL;
	}
      else
	{
	  fputc (*ip, fp);
	  if (*ip == '\r')
	    {
	      len = 0;
	      tty_cleanup = 1;
	    }
	  else
	    len++;
	}
    }
  fflush (fp);
  return len;
}
Пример #10
0
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
	struct wordsplit_node **ptail, const char **pend, int flg)
{
  size_t i = 0;
  const char *defstr = NULL;
  char *value;
  const char *vptr;
  struct wordsplit_node *newnode;
  const char *start = str - 1;
  int rc;
  struct wordsplit ws;
  
  if (ISVARBEG (str[0]))
    {
      for (i = 1; i < len; i++)
	if (!ISVARCHR (str[i]))
	  break;
      *pend = str + i - 1;
    }
  else if (str[0] == '{')
    {
      str++;
      len--;
      for (i = 1; i < len; i++)
	{
	  if (str[i] == ':')
	    {
	      size_t j;
	      
	      defstr = str + i + 1;
	      if (find_closing_paren (str, i + 1, len, &j, "{}"))
		return _wsplt_seterr (wsp, WRDSE_CBRACE);
	      *pend = str + j;
	      break;
	    }
	  else if (str[i] == '}')
	    {
	      defstr = NULL;
	      *pend = str + i;
	      break;
	    }
	  else if (strchr ("-+?=", str[i]))
	    {
	      size_t j;
	      
	      defstr = str + i;
	      if (find_closing_paren (str, i, len, &j, "{}"))
		return _wsplt_seterr (wsp, WRDSE_CBRACE);
	      *pend = str + j;
	      break;
	    }
	}
      if (i == len)
	return _wsplt_seterr (wsp, WRDSE_CBRACE);
    }
  else
    {
      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_WORD | flg;
      newnode->v.word = malloc (3);
      if (!newnode->v.word)
	return _wsplt_nomem (wsp);
      newnode->v.word[0] = '$';
      newnode->v.word[1] = str[0];
      newnode->v.word[2] = 0;
      *pend = str;
      return 0;
    }

  /* Actually expand the variable */
  /* str - start of the variable name
     i   - its length
     defstr - default replacement str */

  if (defstr && strchr("-+?=", defstr[0]) == 0)
    {
      rc = WRDSE_UNDEF;
      defstr = NULL;
    }
  else
    {
      rc = wordsplit_find_env (wsp, str, i, &vptr);
      if (rc == WRDSE_OK)
	{
	  value = strdup (vptr);
	  if (!value)
	    rc = WRDSE_NOSPACE;
	}
      else if (wsp->ws_flags & WRDSF_GETVAR)
	rc = wsp->ws_getvar (&value, str, i, wsp->ws_closure);
      else
	rc = WRDSE_UNDEF;

      if (rc == WRDSE_OK && value[0] == 0 && defstr && defstr[-1] == ':')
	{
	  free (value);
	  rc = WRDSE_UNDEF;
	}
    }
  
  switch (rc)
    {
    case WRDSE_OK:
      if (defstr && *defstr == '+')
	{
	  size_t size = *pend - ++defstr;

	  rc = _wsplt_subsplit (wsp, &ws, defstr, size,
				WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
				(wsp->ws_flags &
				 (WRDSF_NOVAR | WRDSF_NOCMD)));
	  if (rc)
	    return rc;
	  free (value);
	  value = ws.ws_wordv[0];
	  ws.ws_wordv[0] = NULL;
	  wordsplit_free (&ws);
	}
      break;
      
    case WRDSE_UNDEF:
      if (defstr)
	{
	  size_t size;
	  if (*defstr == '-' || *defstr == '=')
	    {
	      size = *pend - ++defstr;

	      rc = _wsplt_subsplit (wsp, &ws, defstr, size,
				    WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
				    (wsp->ws_flags &
				     (WRDSF_NOVAR | WRDSF_NOCMD)));
	      if (rc)
		return rc;

	      value = ws.ws_wordv[0];
	      ws.ws_wordv[0] = NULL;
	      wordsplit_free (&ws);
	      
	      if (defstr[-1] == '=')
		wsplt_assign_var (wsp, str, i, value);
	    }
	  else 
	    {
	      if (*defstr == '?')
		{
		  size = *pend - ++defstr;
		  if (size == 0)
		    wsp->ws_error (_("%.*s: variable null or not set"),
				   (int) i, str);
		  else
		    {
		      rc = _wsplt_subsplit (wsp, &ws, defstr, size,
					    WRDSF_NOSPLIT | WRDSF_WS |
					    WRDSF_QUOTE |
					    (wsp->ws_flags &
					     (WRDSF_NOVAR | WRDSF_NOCMD)));
		      if (rc == 0)
			wsp->ws_error ("%.*s: %s",
				       (int) i, str, ws.ws_wordv[0]);
		      else
			wsp->ws_error ("%.*s: %.*s",
				       (int) i, str, (int) size, defstr);
		      wordsplit_free (&ws);
		    }
		}
	      value = NULL;
	    }
	}
      else if (wsp->ws_flags & WRDSF_UNDEF)
	{
	  _wsplt_seterr (wsp, WRDSE_UNDEF);
	  return 1;
	}
      else
	{
	  if (wsp->ws_flags & WRDSF_WARNUNDEF)
	    wsp->ws_error (_("warning: undefined variable `%.*s'"),
			   (int) i, str);
	  if (wsp->ws_flags & WRDSF_KEEPUNDEF)
	    value = NULL;
	  else
	    {
	      value = strdup ("");
	      if (!value)
		return _wsplt_nomem (wsp);
	    }
	}
      break;
      
    case WRDSE_NOSPACE:
      return _wsplt_nomem (wsp);

    case WRDSE_USERERR:
      if (wsp->ws_errno == WRDSE_USERERR)
	free (wsp->ws_usererr);
      wsp->ws_usererr = value;
      /* fall through */
    default:
      _wsplt_seterr (wsp, rc);
      return 1;
    }

  if (value)
    {
      if (flg & _WSNF_QUOTE)
	{
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
	  newnode->v.word = value;
	}
      else if (*value == 0)
	{
	  free (value);
	  /* Empty string is a special case */
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_NULL;
	}
      else
	{
	  struct wordsplit ws;
	  int i, rc;
	  
	  rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
				WRDSF_NOVAR | WRDSF_NOCMD |
				WRDSF_QUOTE);
	  free (value);
	  if (rc)
	    {
	      _wsplt_seterr_sub (wsp, &ws);
	      wordsplit_free (&ws);
	      return 1;
	    }
	  for (i = 0; i < ws.ws_wordc; i++)
	    {
	      if (wsnode_new (wsp, &newnode))
		return 1;
	      wsnode_insert (wsp, newnode, *ptail, 0);
	      *ptail = newnode;
	      newnode->flags = _WSNF_WORD |
		_WSNF_NOEXPAND |
		(i + 1 < ws.ws_wordc ? (flg & ~_WSNF_JOIN) : flg);
	      newnode->v.word = strdup (ws.ws_wordv[i]);
	      if (!newnode->v.word)
		return _wsplt_nomem (wsp);
	    }
	  wordsplit_free (&ws);
	}
    }
  else if (wsp->ws_flags & WRDSF_KEEPUNDEF)
    {
      size_t size = *pend - start + 1;

      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
      newnode->v.word = malloc (size + 1);
      if (!newnode->v.word)
	return _wsplt_nomem (wsp);
      memcpy (newnode->v.word, start, size);
      newnode->v.word[size] = 0;
    }
  else
    {
      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_NULL;
    }
  return 0;
}
Пример #11
0
static int
expcmd (struct wordsplit *wsp, const char *str, size_t len,
	struct wordsplit_node **ptail, const char **pend, int flg)
{
  int rc;
  size_t j;
  char *value;
  struct wordsplit_node *newnode;
  
  str++;
  len--;

  if (find_closing_paren (str, 0, len, &j, "()"))
    {
      _wsplt_seterr (wsp, WRDSE_PAREN);
      return 1;
    }

  *pend = str + j;
  if (wsp->ws_options & WRDSO_ARGV)
    {
      struct wordsplit ws;

      rc = _wsplt_subsplit (wsp, &ws, str, j,
			    WRDSF_NOVAR | WRDSF_NOCMD |
			    WRDSF_WS | WRDSF_QUOTE);
      if (rc)
	{
	  _wsplt_seterr_sub (wsp, &ws);
	  wordsplit_free (&ws);
	  return 1;
	}
      rc = wsp->ws_command (&value, str, j, ws.ws_wordv, wsp->ws_closure);
      wordsplit_free (&ws);
    }
  else
    rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure);
  
  if (rc == WRDSE_NOSPACE)
    return _wsplt_nomem (wsp);
  else if (rc)
    {
      if (rc == WRDSE_USERERR)
	{
	  if (wsp->ws_errno == WRDSE_USERERR)
	    free (wsp->ws_usererr);
	  wsp->ws_usererr = value;
	}
      _wsplt_seterr (wsp, rc);
      return 1;
    }

  if (value)
    {
      if (flg & _WSNF_QUOTE)
	{
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
	  newnode->v.word = value;
	}
      else if (*value == 0)
	{
	  free (value);
	  /* Empty string is a special case */
	  if (wsnode_new (wsp, &newnode))
	    return 1;
	  wsnode_insert (wsp, newnode, *ptail, 0);
	  *ptail = newnode;
	  newnode->flags = _WSNF_NULL;
	}
      else
	{
	  struct wordsplit ws;
	  int i, rc;

	  rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
				WRDSF_NOVAR | WRDSF_NOCMD |
				WRDSF_WS | WRDSF_QUOTE);
	  free (value);
	  if (rc)
	    {
	      _wsplt_seterr_sub (wsp, &ws);
	      wordsplit_free (&ws);
	      return 1;
	    }
	  for (i = 0; i < ws.ws_wordc; i++)
	    {
	      if (wsnode_new (wsp, &newnode))
		return 1;
	      wsnode_insert (wsp, newnode, *ptail, 0);
	      *ptail = newnode;
	      newnode->flags = _WSNF_WORD |
		_WSNF_NOEXPAND |
		(i + 1 < ws.ws_wordc ? (flg & ~_WSNF_JOIN) : flg);
	      newnode->v.word = strdup (ws.ws_wordv[i]);
	      if (!newnode->v.word)
		return _wsplt_nomem (wsp);
	    }
	  wordsplit_free (&ws);
	}
    }
  else
    {
      if (wsnode_new (wsp, &newnode))
	return 1;
      wsnode_insert (wsp, newnode, *ptail, 0);
      *ptail = newnode;
      newnode->flags = _WSNF_NULL;
    }
  return 0;
}