Пример #1
0
/* Adds a new column to 'table' just to the right of any existing column, with
 * 'heading' as a title for the column.  'heading' must be a valid printf()
 * format specifier.
 *
 * Columns must be added before any data is put into 'table'. */
void
table_add_column(struct table *table, const char *heading, ...)
{
    struct column *column;
    va_list args;

    assert(!table->n_rows);
    if (table->n_columns >= table->allocated_columns) {
        table->columns = x2nrealloc(table->columns, &table->allocated_columns,
                                    sizeof *table->columns);
    }
    column = &table->columns[table->n_columns++];

    va_start(args, heading);
    column->heading = xvasprintf(heading, args);
    va_end(args);
}
Пример #2
0
void
add_exclude (struct exclude *ex, char const *pattern, int options)
{
  struct exclude_segment *seg;

  if ((options & EXCLUDE_WILDCARDS)
      && fnmatch_pattern_has_wildcards (pattern, options))
    {
      struct exclude_pattern *pat;
      struct patopts *patopts;

      if (ex->tail && ex->tail->type == exclude_pattern
          && ((ex->tail->options & EXCLUDE_INCLUDE) ==
              (options & EXCLUDE_INCLUDE)))
        seg = ex->tail;
      else
        seg = new_exclude_segment (ex, exclude_pattern, options);

      pat = &seg->v.pat;
      if (pat->exclude_count == pat->exclude_alloc)
        pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc,
                                   sizeof *pat->exclude);
      patopts = &pat->exclude[pat->exclude_count++];
      patopts->pattern = pattern;
      patopts->options = options;
    }
  else
    {
      char *str, *p;
#define EXCLUDE_HASH_FLAGS (EXCLUDE_INCLUDE|EXCLUDE_ANCHORED|\
                            FNM_LEADING_DIR|FNM_CASEFOLD)
      if (ex->tail && ex->tail->type == exclude_hash
          && ((ex->tail->options & EXCLUDE_HASH_FLAGS) ==
              (options & EXCLUDE_HASH_FLAGS)))
        seg = ex->tail;
      else
        seg = new_exclude_segment (ex, exclude_hash, options);

      str = xstrdup (pattern);
      if (options & EXCLUDE_WILDCARDS)
        unescape_pattern (str);
      p = hash_insert (seg->v.table, str);
      if (p != str)
        free (str);
    }
}
Пример #3
0
/* Registers 'file' to be unlinked when the program terminates via exit() or a
 * fatal signal. */
void
fatal_signal_add_file_to_unlink(const char *file)
{
    static bool added_hook = false;
    if (!added_hook) {
        added_hook = true;
        fatal_signal_add_hook(unlink_files, NULL, true);
        fatal_signal_add_hook(destroy_pipeline, NULL, true);
    }

    fatal_signal_block();
    if (n_files >= max_files) {
        files = x2nrealloc(files, &max_files, sizeof *files);
    }
    files[n_files++] = xstrdup(file);
    fatal_signal_unblock();
}
Пример #4
0
static size_t
readname (char **name, size_t *size, FILE *stream)
{
  int c;
  size_t name_index = 0;

  /* Skip blank space.  */
  while ((c = getc (stream)) != EOF && isspace (c))
    /* Do nothing. */ ;

  for (;;)
    {
      if (*size <= name_index)
        *name = x2nrealloc (*name, size, sizeof **name);
      if (c == EOF || isspace (c))
        break;
      (*name)[name_index++] = c;
      c = getc (stream);
    }
  (*name)[name_index] = '\0';
  return name_index;
}
Пример #5
0
int
read_utmp (char const *file, size_t *n_entries, STRUCT_UTMP **utmp_buf,
	   int options)
{
  size_t n_read = 0;
  size_t n_alloc = 0;
  STRUCT_UTMP *utmp = NULL;
  int saved_errno;
  FILE *f = fopen (file, "r");

  if (! f)
    return -1;

  for (;;)
    {
      if (n_read == n_alloc)
	utmp = x2nrealloc (utmp, &n_alloc, sizeof *utmp);
      if (fread (&utmp[n_read], sizeof utmp[n_read], 1, f) == 0)
	break;
      n_read += desirable_utmp_entry (&utmp[n_read], options);
    }

  saved_errno = ferror (f) ? errno : 0;
  if (fclose (f) != 0)
    saved_errno = errno;
  if (saved_errno != 0)
    {
      free (utmp);
      errno = saved_errno;
      return -1;
    }

  *n_entries = n_read;
  *utmp_buf = utmp;

  return 0;
}
Пример #6
0
/* DIR is the operand of a -C option; add it to vector of chdir targets,
   and return the index of its location.  */
int
chdir_arg (char const *dir)
{
  if (wd_count == wd_alloc)
    {
      if (wd_alloc == 0)
	{
	  wd_alloc = 2;
	  wd = xmalloc (sizeof *wd * wd_alloc);
	}
      else
	wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);

      if (! wd_count)
	{
	  wd[wd_count].name = ".";
	  wd[wd_count].fd = AT_FDCWD;
	  wd_count++;
	}
    }

  /* Optimize the common special case of the working directory,
     or the working directory as a prefix.  */
  if (dir[0])
    {
      while (dir[0] == '.' && ISSLASH (dir[1]))
	for (dir += 2;  ISSLASH (*dir);  dir++)
	  continue;
      if (! dir[dir[0] == '.'])
	return wd_count - 1;
    }

  wd[wd_count].name = dir;
  wd[wd_count].fd = 0;
  return wd_count++;
}
Пример #7
0
char *
streamsavedir (DIR *dirp, enum savedir_option option)
{
  char *name_space = NULL;
  size_t allocated = 0;
  direntry_t *entries = NULL;
  size_t entries_allocated = 0;
  size_t entries_used = 0;
  size_t used = 0;
  int readdir_errno;
  comparison_function cmp = comparison_function_table[option];

  if (dirp == NULL)
    return NULL;

  for (;;)
    {
      struct dirent const *dp;
      char const *entry;

      errno = 0;
      dp = readdir (dirp);
      if (! dp)
        break;

      /* Skip "", ".", and "..".  "" is returned by at least one buggy
         implementation: Solaris 2.4 readdir on NFS file systems.  */
      entry = dp->d_name;
      if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
        {
          size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
          if (cmp)
            {
              if (entries_allocated == entries_used)
                {
                  size_t n = entries_allocated;
                  entries = x2nrealloc (entries, &n, sizeof *entries);
                  entries_allocated = n;
                }
              entries[entries_used].name = xstrdup (entry);
#if D_INO_IN_DIRENT
              entries[entries_used].ino = dp->d_ino;
#endif
              entries_used++;
            }
          else
            {
              if (allocated - used <= entry_size)
                {
                  size_t n = used + entry_size;
                  if (n < used)
                    xalloc_die ();
                  name_space = x2nrealloc (name_space, &n, 1);
                  allocated = n;
                }
              memcpy (name_space + used, entry, entry_size);
            }
          used += entry_size;
        }
    }

  readdir_errno = errno;
  if (readdir_errno != 0)
    {
      free (entries);
      free (name_space);
      errno = readdir_errno;
      return NULL;
    }

  if (cmp)
    {
      size_t i;

      qsort (entries, entries_used, sizeof *entries, cmp);
      name_space = xmalloc (used + 1);
      used = 0;
      for (i = 0; i < entries_used; i++)
        {
          char *dest = name_space + used;
          used += stpcpy (dest, entries[i].name) - dest + 1;
          free (entries[i].name);
        }
      free (entries);
    }
  else if (used == allocated)
    name_space = xrealloc (name_space, used + 1);

  name_space[used] = '\0';
  return name_space;
}
Пример #8
0
void *x2realloc( void *p, size_t *pn )
{
  return x2nrealloc( p, pn, ebp_16 );
}
Пример #9
0
static char*
do_time_format (const char *fmt, const struct tm *p, const char *ns, size_t ns_size)
{
  static char *buf = NULL;
  static size_t buf_size;
  char *timefmt = NULL;
  struct tm altered_time;


  /* If the format expands to nothing (%p in some locales, for
   * example), strftime can return 0.  We actually want to distinguish
   * the error case where the buffer is too short, so we just prepend
   * an otherwise uninteresting character to prevent the no-output
   * case.
   */
  timefmt = xmalloc (strlen (fmt) + 2u);
  timefmt[0] = '_';
  memcpy (timefmt + 1, fmt, strlen (fmt) + 1);

  /* altered_time is a similar time, but in which both
   * digits of the seconds field are different.
   */
  altered_time = *p;
  if (altered_time.tm_sec >= 11)
    altered_time.tm_sec -= 11;
  else
    altered_time.tm_sec += 11;

  /* If we call strftime() with buf_size=0, the program will coredump
   * on Solaris, since it unconditionally writes the terminating null
   * character.
   */
  if (buf == NULL)
    {
      buf_size = 1u;
      buf = xmalloc (buf_size);
    }
  while (true)
    {
      /* I'm not sure that Solaris will return 0 when the buffer is too small.
       * Therefore we do not check for (buf_used != 0) as the termination
       * condition.
       */
      size_t buf_used = strftime (buf, buf_size, timefmt, p);
      if (buf_used              /* Conforming POSIX system */
          && (buf_used < buf_size)) /* Solaris workaround */
        {
          char *altbuf;
          size_t i = 0, n = 0;
          size_t final_len = (buf_used
                              + 1u /* for \0 */
                              + ns_size);
          buf = xrealloc (buf, final_len);
          buf_size = final_len;
          altbuf = xmalloc (final_len);
          strftime (altbuf, buf_size, timefmt, &altered_time);

          /* Find the seconds digits; they should be the only changed part.
           * In theory the result of the two formatting operations could differ in
           * more than just one sequence of decimal digits (for example %X might
           * in theory return a spelled-out time like "thirty seconds past noon").
           * When that happens, we just avoid inserting the nanoseconds field.
           */
          if (scan_for_digit_differences (buf, altbuf, &i, &n)
              && (2==n) && !isdigit ((unsigned char)buf[i+n]))
            {
              const size_t end_of_seconds = i + n;
              const size_t suffix_len = buf_used-(end_of_seconds)+1;

              /* Move the tail (including the \0).  Note that this
               * is a move of an overlapping memory block, so we
               * must use memmove instead of memcpy.  Then insert
               * the nanoseconds (but not its trailing \0).
               */
              assert (end_of_seconds + ns_size + suffix_len == final_len);
              memmove (buf+end_of_seconds+ns_size,
                       buf+end_of_seconds,
                       suffix_len);
              memcpy (buf+i+n, ns, ns_size);
            }
          else
            {
              /* No seconds digits.  No need to insert anything. */
            }
          /* The first character of buf is the underscore, which we actually
           * don't want.
           */
          free (timefmt);
          free (altbuf);
          return buf+1;
        }
      else
        {
          buf = x2nrealloc (buf, &buf_size, sizeof *buf);
        }
    }
}
Пример #10
0
static void
do_listen(struct ovs_cmdl_context *ctx)
{
    struct pstream *pstream;
    struct jsonrpc **rpcs;
    size_t n_rpcs, allocated_rpcs;
    bool done;
    int error;

    error = jsonrpc_pstream_open(ctx->argv[1], &pstream, DSCP_DEFAULT);
    if (error) {
        ovs_fatal(error, "could not listen on \"%s\"", ctx->argv[1]);
    }

    daemonize();

    rpcs = NULL;
    n_rpcs = allocated_rpcs = 0;
    done = false;
    for (;;) {
        struct stream *stream;
        size_t i;

        /* Accept new connections. */
        error = pstream_accept(pstream, &stream);
        if (!error) {
            if (n_rpcs >= allocated_rpcs) {
                rpcs = x2nrealloc(rpcs, &allocated_rpcs, sizeof *rpcs);
            }
            rpcs[n_rpcs++] = jsonrpc_open(stream);
        } else if (error != EAGAIN) {
            ovs_fatal(error, "pstream_accept failed");
        }

        /* Service existing connections. */
        for (i = 0; i < n_rpcs; ) {
            struct jsonrpc *rpc = rpcs[i];
            struct jsonrpc_msg *msg;

            jsonrpc_run(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                error = jsonrpc_recv(rpc, &msg);
                if (!error) {
                    error = handle_rpc(rpc, msg, &done);
                    jsonrpc_msg_destroy(msg);
                } else if (error == EAGAIN) {
                    error = 0;
                }
            }

            if (!error) {
                error = jsonrpc_get_status(rpc);
            }
            if (error) {
                jsonrpc_close(rpc);
                ovs_error(error, "connection closed");
                memmove(&rpcs[i], &rpcs[i + 1],
                        (n_rpcs - i - 1) * sizeof *rpcs);
                n_rpcs--;
            } else {
                i++;
            }
        }

        /* Wait for something to do. */
        if (done && !n_rpcs) {
            break;
        }
        pstream_wait(pstream);
        for (i = 0; i < n_rpcs; i++) {
            struct jsonrpc *rpc = rpcs[i];

            jsonrpc_wait(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                jsonrpc_recv_wait(rpc);
            }
        }
        poll_block();
    }
    free(rpcs);
    pstream_close(pstream);
}
Пример #11
0
void
add_exclude (struct exclude *ex, char const *pattern, int options)
{
  struct exclude_segment *seg;
  struct exclude_pattern *pat;
  struct patopts *patopts;

  if ((options & (EXCLUDE_REGEX|EXCLUDE_WILDCARDS))
      && fnmatch_pattern_has_wildcards (pattern, options))
    {
      if (! (ex->head && ex->head->type == exclude_pattern
	     && ((ex->head->options & EXCLUDE_INCLUDE)
		 == (options & EXCLUDE_INCLUDE))))
	new_exclude_segment (ex, exclude_pattern, options);

      seg = ex->head;

      pat = &seg->v.pat;
      if (pat->exclude_count == pat->exclude_alloc)
        pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc,
                                   sizeof *pat->exclude);
      patopts = &pat->exclude[pat->exclude_count++];

      patopts->options = options;
      if (options & EXCLUDE_REGEX)
	{
	  int rc;
	  int cflags = REG_NOSUB|REG_EXTENDED|
	               ((options & FNM_CASEFOLD) ? REG_ICASE : 0);

	  if (options & FNM_LEADING_DIR)
	    {
	      char *tmp;
	      size_t len = strlen (pattern);

	      while (len > 0 && ISSLASH (pattern[len-1]))
		--len;

	      if (len == 0)
		rc = 1;
	      else
		{
		  tmp = xmalloc (len + 7);
		  memcpy (tmp, pattern, len);
		  strcpy (tmp + len, "(/.*)?");
		  rc = regcomp (&patopts->v.re, tmp, cflags);
		  free (tmp);
		}
	    }
	  else
	    rc = regcomp (&patopts->v.re, pattern, cflags);

	  if (rc)
	    {
	      pat->exclude_count--;
	      return;
	    }
	}
      else
	{
	  if (options & EXCLUDE_ALLOC)
	    {
	      pattern = xstrdup (pattern);
	      exclude_add_pattern_buffer (ex, (char*) pattern);
	    }
	  patopts->v.pattern = pattern;
	}
    }
  else
    {
      char *str, *p;
      int exclude_hash_flags = (EXCLUDE_INCLUDE | EXCLUDE_ANCHORED
                                | FNM_LEADING_DIR | FNM_CASEFOLD);
      if (! (ex->head && ex->head->type == exclude_hash
             && ((ex->head->options & exclude_hash_flags)
                 == (options & exclude_hash_flags))))
        new_exclude_segment (ex, exclude_hash, options);
      seg = ex->head;

      str = xstrdup (pattern);
      if ((options & (EXCLUDE_WILDCARDS | FNM_NOESCAPE)) == EXCLUDE_WILDCARDS)
        unescape_pattern (str);
      p = hash_insert (seg->v.table, str);
      if (p != str)
        free (str);
    }
}
Пример #12
0
size_t
readtoken (FILE *stream,
           const char *delim,
           size_t n_delim,
           token_buffer *tokenbuffer)
{
    char *p;
    int c;
    size_t i, n;
    static const char *saved_delim = NULL;
    static char isdelim[256];
    bool same_delimiters;

    if (delim == NULL && saved_delim == NULL)
        abort ();

    same_delimiters = false;
    if (delim != saved_delim && saved_delim != NULL)
    {
        same_delimiters = true;
        for (i = 0; i < n_delim; i++)
        {
            if (delim[i] != saved_delim[i])
            {
                same_delimiters = false;
                break;
            }
        }
    }

    if (!same_delimiters)
    {
        size_t j;
        saved_delim = delim;
        memset (isdelim, 0, sizeof isdelim);
        for (j = 0; j < n_delim; j++)
        {
            unsigned char ch = delim[j];
            isdelim[ch] = 1;
        }
    }

    /* FIXME: don't fool with this caching.  Use strchr instead.  */
    /* skip over any leading delimiters */
    for (c = getc (stream); c >= 0 && isdelim[c]; c = getc (stream))
    {
        /* empty */
    }

    p = tokenbuffer->buffer;
    n = tokenbuffer->size;
    i = 0;
    for (;;)
    {
        if (c < 0 && i == 0)
            return -1;

        if (i == n)
            p = x2nrealloc (p, &n, sizeof *p);

        if (c < 0)
        {
            p[i] = 0;
            break;
        }
        if (isdelim[c])
        {
            p[i] = 0;
            break;
        }
        p[i++] = c;
        c = getc (stream);
    }

    tokenbuffer->buffer = p;
    tokenbuffer->size = n;
    return i;
}
Пример #13
0
static int
combine_files (enum comb_command_type command,
               struct lexer *lexer, struct dataset *ds)
{
  struct comb_proc proc;

  bool saw_by = false;
  bool saw_sort = false;
  struct casereader *active_file = NULL;

  char *first_name = NULL;
  char *last_name = NULL;

  struct taint *taint = NULL;

  size_t n_tables = 0;
  size_t allocated_files = 0;

  size_t i;

  proc.files = NULL;
  proc.n_files = 0;
  proc.dict = dict_create (get_default_encoding ());
  proc.output = NULL;
  proc.matcher = NULL;
  subcase_init_empty (&proc.by_vars);
  proc.first = NULL;
  proc.last = NULL;
  proc.buffered_case = NULL;
  proc.prev_BY = NULL;

  dict_set_case_limit (proc.dict, dict_get_case_limit (dataset_dict (ds)));

  lex_match (lexer, T_SLASH);
  for (;;)
    {
      struct comb_file *file;
      enum comb_file_type type;

      if (lex_match_id (lexer, "FILE"))
        type = COMB_FILE;
      else if (command == COMB_MATCH && lex_match_id (lexer, "TABLE"))
        {
          type = COMB_TABLE;
          n_tables++;
        }
      else
        break;
      lex_match (lexer, T_EQUALS);

      if (proc.n_files >= allocated_files)
        proc.files = x2nrealloc (proc.files, &allocated_files,
                                sizeof *proc.files);
      file = &proc.files[proc.n_files++];
      file->type = type;
      subcase_init_empty (&file->by_vars);
      subcase_init_empty (&file->src);
      subcase_init_empty (&file->dst);
      file->mv = NULL;
      file->handle = NULL;
      file->dict = NULL;
      file->reader = NULL;
      file->data = NULL;
      file->is_sorted = true;
      file->in_name = NULL;
      file->in_var = NULL;

      if (lex_match (lexer, T_ASTERISK))
        {
          if (!dataset_has_source (ds))
            {
              msg (SE, _("Cannot specify the active dataset since none "
                         "has been defined."));
              goto error;
            }

          if (proc_make_temporary_transformations_permanent (ds))
            msg (SE, _("This command may not be used after TEMPORARY when "
                       "the active dataset is an input source.  "
                       "Temporary transformations will be made permanent."));

          file->dict = dict_clone (dataset_dict (ds));
        }
      else
        {
          file->handle = fh_parse (lexer, FH_REF_FILE, dataset_session (ds));
          if (file->handle == NULL)
            goto error;

          file->reader = any_reader_open (file->handle, NULL, &file->dict);
          if (file->reader == NULL)
            goto error;
        }

      while (lex_match (lexer, T_SLASH))
        if (lex_match_id (lexer, "RENAME"))
          {
            if (!parse_dict_rename (lexer, file->dict))
              goto error;
          }
        else if (lex_match_id (lexer, "IN"))
          {
            lex_match (lexer, T_EQUALS);
            if (lex_token (lexer) != T_ID)
              {
                lex_error (lexer, NULL);
                goto error;
              }

            if (file->in_name)
              {
                msg (SE, _("Multiple IN subcommands for a single FILE or "
                           "TABLE."));
                goto error;
              }
            file->in_name = xstrdup (lex_tokcstr (lexer));
            lex_get (lexer);
          }
        else if (lex_match_id (lexer, "SORT"))
          {
            file->is_sorted = false;
            saw_sort = true;
          }

      if (!merge_dictionary (proc.dict, file))
        goto error;
    }

  while (lex_token (lexer) != T_ENDCMD)
    {
      if (lex_match (lexer, T_BY))
	{
          const struct variable **by_vars;
          size_t i;
          bool ok;

	  if (saw_by)
	    {
              lex_sbc_only_once ("BY");
	      goto error;
	    }
          saw_by = true;

	  lex_match (lexer, T_EQUALS);
          if (!parse_sort_criteria (lexer, proc.dict, &proc.by_vars,
                                    &by_vars, NULL))
	    goto error;

          ok = true;
          for (i = 0; i < proc.n_files; i++)
            {
              struct comb_file *file = &proc.files[i];
              size_t j;

              for (j = 0; j < subcase_get_n_fields (&proc.by_vars); j++)
                {
                  const char *name = var_get_name (by_vars[j]);
                  struct variable *var = dict_lookup_var (file->dict, name);
                  if (var != NULL)
                    subcase_add_var (&file->by_vars, var,
                                     subcase_get_direction (&proc.by_vars, j));
                  else
                    {
                      if (file->handle != NULL)
                        msg (SE, _("File %s lacks BY variable %s."),
                             fh_get_name (file->handle), name);
                      else
                        msg (SE, _("Active dataset lacks BY variable %s."),
                             name);
                      ok = false;
                    }
                }
              assert (!ok || subcase_conformable (&file->by_vars,
                                                  &proc.files[0].by_vars));
            }
          free (by_vars);

          if (!ok)
            goto error;
	}
      else if (command != COMB_UPDATE && lex_match_id (lexer, "FIRST"))
        {
          if (first_name != NULL)
            {
              lex_sbc_only_once ("FIRST");
              goto error;
            }

	  lex_match (lexer, T_EQUALS);
          if (!lex_force_id (lexer))
            goto error;
          first_name = xstrdup (lex_tokcstr (lexer));
          lex_get (lexer);
        }
      else if (command != COMB_UPDATE && lex_match_id (lexer, "LAST"))
        {
          if (last_name != NULL)
            {
              lex_sbc_only_once ("LAST");
              goto error;
            }

	  lex_match (lexer, T_EQUALS);
          if (!lex_force_id (lexer))
            goto error;
          last_name = xstrdup (lex_tokcstr (lexer));
          lex_get (lexer);
        }
      else if (lex_match_id (lexer, "MAP"))
	{
	  /* FIXME. */
	}
      else if (lex_match_id (lexer, "DROP"))
        {
          if (!parse_dict_drop (lexer, proc.dict))
            goto error;
        }
      else if (lex_match_id (lexer, "KEEP"))
        {
          if (!parse_dict_keep (lexer, proc.dict))
            goto error;
        }
      else
	{
	  lex_error (lexer, NULL);
	  goto error;
	}

      if (!lex_match (lexer, T_SLASH) && lex_token (lexer) != T_ENDCMD)
        {
          lex_end_of_command (lexer);
          goto error;
        }
    }

  if (!saw_by)
    {
      if (command == COMB_UPDATE)
        {
          lex_sbc_missing ("BY");
          goto error;
        }
      if (n_tables)
        {
          msg (SE, _("BY is required when %s is specified."), "TABLE");
          goto error;
        }
      if (saw_sort)
        {
          msg (SE, _("BY is required when %s is specified."), "SORT");
          goto error;
        }
    }

  /* Add IN, FIRST, and LAST variables to master dictionary. */
  for (i = 0; i < proc.n_files; i++)
    {
      struct comb_file *file = &proc.files[i];
      if (!create_flag_var ("IN", file->in_name, proc.dict, &file->in_var))
        goto error;
    }
  if (!create_flag_var ("FIRST", first_name, proc.dict, &proc.first)
      || !create_flag_var ("LAST", last_name, proc.dict, &proc.last))
    goto error;

  dict_delete_scratch_vars (proc.dict);
  dict_compact_values (proc.dict);

  /* Set up mapping from each file's variables to master
     variables. */
  for (i = 0; i < proc.n_files; i++)
    {
      struct comb_file *file = &proc.files[i];
      size_t src_var_cnt = dict_get_var_cnt (file->dict);
      size_t j;

      file->mv = xnmalloc (src_var_cnt, sizeof *file->mv);
      for (j = 0; j < src_var_cnt; j++)
        {
          struct variable *src_var = dict_get_var (file->dict, j);
          struct variable *dst_var = dict_lookup_var (proc.dict,
                                                      var_get_name (src_var));
          if (dst_var != NULL)
            {
              size_t n = subcase_get_n_fields (&file->src);
              file->mv[n] = var_get_missing_values (src_var);
              subcase_add_var (&file->src, src_var, SC_ASCEND);
              subcase_add_var (&file->dst, dst_var, SC_ASCEND);
            }
        }
    }

  proc.output = autopaging_writer_create (dict_get_proto (proc.dict));
  taint = taint_clone (casewriter_get_taint (proc.output));

  /* Set up case matcher. */
  proc.matcher = case_matcher_create ();
  for (i = 0; i < proc.n_files; i++)
    {
      struct comb_file *file = &proc.files[i];
      if (file->reader == NULL)
        {
          if (active_file == NULL)
            {
              proc_discard_output (ds);
              file->reader = active_file = proc_open_filtering (ds, false);
            }
          else
            file->reader = casereader_clone (active_file);
        }
      if (!file->is_sorted)
        file->reader = sort_execute (file->reader, &file->by_vars);
      taint_propagate (casereader_get_taint (file->reader), taint);
      file->data = casereader_read (file->reader);
      if (file->type == COMB_FILE)
        case_matcher_add_input (proc.matcher, &file->by_vars,
                                &file->data, &file->is_minimal);
    }

  if (command == COMB_ADD)
    execute_add_files (&proc);
  else if (command == COMB_MATCH)
    execute_match_files (&proc);
  else if (command == COMB_UPDATE)
    execute_update (&proc);
  else
    NOT_REACHED ();

  case_matcher_destroy (proc.matcher);
  proc.matcher = NULL;
  close_all_comb_files (&proc);
  if (active_file != NULL)
    proc_commit (ds);

  dataset_set_dict (ds, proc.dict);
  dataset_set_source (ds, casewriter_make_reader (proc.output));
  proc.dict = NULL;
  proc.output = NULL;

  free_comb_proc (&proc);

  free (first_name);
  free (last_name);

  return taint_destroy (taint) ? CMD_SUCCESS : CMD_CASCADING_FAILURE;

 error:
  if (active_file != NULL)
    proc_commit (ds);
  free_comb_proc (&proc);
  taint_destroy (taint);
  free (first_name);
  free (last_name);
  return CMD_CASCADING_FAILURE;
}
Пример #14
0
/* get all xattrs from file given by FILE_NAME or FD (when non-zero).  This
   includes all the user.*, security.*, system.*, etc. available domains */
void
xattrs_xattrs_get (int parentfd, char const *file_name,
                   struct tar_stat_info *st, int fd)
{
  if (xattrs_option > 0)
    {
#ifndef HAVE_XATTRS
      static int done = 0;
      if (!done)
        WARN ((0, 0, _("XATTR support is not available")));
      done = 1;
#else
      static size_t xsz = 1024;
      static char *xatrs = NULL;
      ssize_t xret = -1;

      if (!xatrs)
	xatrs = x2nrealloc (xatrs, &xsz, 1);

      while (((fd == 0) ?
              ((xret =
                llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) :
	      ((xret = flistxattr (fd, xatrs, xsz)) == -1))
             && (errno == ERANGE))
        {
	  xatrs = x2nrealloc (xatrs, &xsz, 1);
        }

      if (xret == -1)
        call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name);
      else
        {
          const char *attr = xatrs;
          static size_t asz = 1024;
          static char *val = NULL;

          if (!val)
            val = x2nrealloc (val, &asz, 1);

          while (xret > 0)
            {
              size_t len = strlen (attr);
              ssize_t aret = 0;

              /* Archive all xattrs during creation, decide at extraction time
               * which ones are of interest/use for the target filesystem. */
              while (((fd == 0)
                      ? ((aret = lgetxattrat (parentfd, file_name, attr,
                                              val, asz)) == -1)
                      : ((aret = fgetxattr (fd, attr, val, asz)) == -1))
                     && (errno == ERANGE))
                {
		  val = x2nrealloc (val, &asz, 1);
                }

              if (aret != -1)
                xheader_xattr_add (st, attr, val, aret);
              else if (errno != ENOATTR)
                call_arg_warn ((fd == 0) ? "lgetxattrat"
                               : "fgetxattr", file_name);

              attr += len + 1;
              xret -= len + 1;
            }
        }
#endif
    }
}
Пример #15
0
/* Opens file 'file_name' and reads each line as a flow_mod or a group_mod,
 * depending on the first keyword on each line.  Stores each flow and group
 * mods in '*bms', an array allocated on the caller's behalf, and the number of
 * messages in '*n_bms'.
 *
 * Returns NULL if successful, otherwise a malloc()'d string describing the
 * error.  The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
parse_ofp_bundle_file(const char *file_name,
                      const struct ofputil_port_map *port_map,
                      const struct ofputil_table_map *table_map,
                      struct ofputil_bundle_msg **bms, size_t *n_bms,
                      enum ofputil_protocol *usable_protocols)
{
    size_t allocated_bms;
    char *error = NULL;
    int line_number;
    FILE *stream;
    struct ds ds;

    *usable_protocols = OFPUTIL_P_ANY;

    *bms = NULL;
    *n_bms = 0;

    stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
    if (stream == NULL) {
        return xasprintf("%s: open failed (%s)",
                         file_name, ovs_strerror(errno));
    }

    allocated_bms = *n_bms;
    ds_init(&ds);
    line_number = 0;
    while (!ds_get_preprocessed_line(&ds, stream, &line_number)) {
        enum ofputil_protocol usable;
        char *s = ds_cstr(&ds);
        size_t len;

        if (*n_bms >= allocated_bms) {
            struct ofputil_bundle_msg *new_bms;

            new_bms = x2nrealloc(*bms, &allocated_bms, sizeof **bms);
            for (size_t i = 0; i < *n_bms; i++) {
                if (new_bms[i].type == OFPTYPE_GROUP_MOD) {
                    ovs_list_moved(&new_bms[i].gm.buckets,
                                   &(*bms)[i].gm.buckets);
                }
            }
            *bms = new_bms;
        }

        s += strspn(s, " \t\r\n");   /* Skip white space. */
        len = strcspn(s, ", \t\r\n"); /* Get length of the first token. */

        if (!strncmp(s, "flow", len)) {
            s += len;
            error = parse_ofp_flow_mod_str(&(*bms)[*n_bms].fm, s, port_map,
                                           table_map, -2, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_FLOW_MOD;
        } else if (!strncmp(s, "group", len)) {
            s += len;
            error = parse_ofp_group_mod_str(&(*bms)[*n_bms].gm, -2, s,
                                            port_map, table_map, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_GROUP_MOD;
        } else if (!strncmp(s, "packet-out", len)) {
            s += len;
            error = parse_ofp_packet_out_str(&(*bms)[*n_bms].po, s, port_map,
                                             table_map, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_PACKET_OUT;
        } else {
            error = xasprintf("Unsupported bundle message type: %.*s",
                              (int)len, s);
            break;
        }

        *usable_protocols &= usable; /* Each line can narrow the set. */
        *n_bms += 1;
    }

    ds_destroy(&ds);
    if (stream != stdin) {
        fclose(stream);
    }

    if (error) {
        char *err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
        free(error);

        ofputil_free_bundle_msgs(*bms, *n_bms);
        *bms = NULL;
        *n_bms = 0;
        return err_msg;
    }
    return NULL;
}