예제 #1
0
파일: config_win.c 프로젝트: vocho/openqnx
svn_error_t *
svn_config__open_file(FILE **pfile,
                      const char *filename,
                      const char *mode,
                      apr_pool_t *pool)
{
  int style;
  apr_status_t apr_err = apr_filepath_encoding(&style, pool);

  if (apr_err)
    return svn_error_wrap_apr(apr_err,
                              "Can't determine the native path encoding");

  if (style == APR_FILEPATH_ENCODING_UTF8)
    {
      WCHAR *filename_ucs2;
      WCHAR *mode_ucs2;

      SVN_ERR(utf8_to_ucs2(&filename_ucs2, filename, pool));
      SVN_ERR(utf8_to_ucs2(&mode_ucs2, mode, pool));
      *pfile = _wfopen(filename_ucs2, mode_ucs2);
    }
  else if (style == APR_FILEPATH_ENCODING_LOCALE)
    {
      const char *filename_native;
      SVN_ERR(svn_utf_cstring_from_utf8(&filename_native, filename, pool));
      *pfile = fopen(filename_native, mode);
    }
  else
    {
      /* There is no third option on Windows; we should never get here. */
      return svn_error_createf(APR_EINVAL, NULL,
                               "Unknown native path encoding (%d)", style);
    }

  return SVN_NO_ERROR;
}
예제 #2
0
/* Create a Berkeley DB environment. */
static svn_error_t *
create_env(bdb_env_t **bdbp, const char *path, apr_pool_t *pool)
{
  int db_err;
  bdb_env_t *bdb;
  const char *path_bdb;
  char *tmp_path, *tmp_path_bdb;
  apr_size_t path_size, path_bdb_size;

#if SVN_BDB_PATH_UTF8
  path_bdb = svn_dirent_local_style(path, pool);
#else
  SVN_ERR(svn_utf_cstring_from_utf8(&path_bdb,
                                    svn_dirent_local_style(path, pool),
                                    pool));
#endif

  /* Allocate the whole structure, including strings, from the heap,
     because it must survive the cache pool cleanup. */
  path_size = strlen(path) + 1;
  path_bdb_size = strlen(path_bdb) + 1;
  /* Using calloc() to ensure the padding bytes in bdb->key (which is used as
   * a hash key) are zeroed. */
  bdb = calloc(1, sizeof(*bdb) + path_size + path_bdb_size);

  /* We must initialize this now, as our callers may assume their bdb
     pointer is valid when checking for errors.  */
  apr_pool_cleanup_register(pool, bdb, cleanup_env, apr_pool_cleanup_null);
  apr_cpystrn(bdb->errpfx_string, BDB_ERRPFX_STRING,
              sizeof(bdb->errpfx_string));
  bdb->path = tmp_path = (char*)(bdb + 1);
  bdb->path_bdb = tmp_path_bdb = tmp_path + path_size;
  apr_cpystrn(tmp_path, path, path_size);
  apr_cpystrn(tmp_path_bdb, path_bdb, path_bdb_size);
  bdb->pool = pool;
  *bdbp = bdb;

#if APR_HAS_THREADS
  {
    apr_status_t apr_err = apr_threadkey_private_create(&bdb->error_info,
                                                        cleanup_error_info,
                                                        pool);
    if (apr_err)
      return svn_error_create(apr_err, NULL,
                              "Can't allocate thread-specific storage"
                              " for the Berkeley DB environment descriptor");
  }
#endif /* APR_HAS_THREADS */

  db_err = db_env_create(&(bdb->env), 0);
  if (!db_err)
    {
      /* See the documentation at bdb_env_t's definition why the
         (char *) cast is safe and why it is done. */
      bdb->env->set_errpfx(bdb->env, (char *) bdb);

      /* bdb_error_gatherer is in parens to stop macro expansion. */
      bdb->env->set_errcall(bdb->env, (bdb_error_gatherer));

      /* Needed on Windows in case Subversion and Berkeley DB are using
         different C runtime libraries  */
      db_err = bdb->env->set_alloc(bdb->env, malloc, realloc, free);

      /* If we detect a deadlock, select a transaction to abort at
         random from those participating in the deadlock.  */
      if (!db_err)
        db_err = bdb->env->set_lk_detect(bdb->env, DB_LOCK_RANDOM);
    }
  return convert_bdb_error(bdb, db_err);
}
예제 #3
0
svn_error_t *
svn_cl__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
                               const char **tmpfile_left /* UTF-8! */,
                               const char *editor_cmd,
                               const char *base_dir /* UTF-8! */,
                               const svn_string_t *contents /* UTF-8! */,
                               const char *filename,
                               apr_hash_t *config,
                               svn_boolean_t as_text,
                               const char *encoding,
                               apr_pool_t *pool)
{
  const char *editor;
  const char *cmd;
  apr_file_t *tmp_file;
  const char *tmpfile_name;
  const char *tmpfile_native;
  const char *tmpfile_apr, *base_dir_apr;
  svn_string_t *translated_contents;
  apr_status_t apr_err, apr_err2;
  apr_size_t written;
  apr_finfo_t finfo_before, finfo_after;
  svn_error_t *err = SVN_NO_ERROR, *err2;
  char *old_cwd;
  int sys_err;
  svn_boolean_t remove_file = TRUE;

  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));

  /* Convert file contents from UTF-8/LF if desired. */
  if (as_text)
    {
      const char *translated;
      SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
                                           APR_EOL_STR, FALSE,
                                           NULL, FALSE, pool));
      translated_contents = svn_string_create("", pool);
      if (encoding)
        SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
                                              translated, encoding, pool));
      else
        SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
                                          translated, pool));
      translated_contents->len = strlen(translated_contents->data);
    }
  else
    translated_contents = svn_string_dup(contents, pool);

  /* Move to BASE_DIR to avoid getting characters that need quoting
     into tmpfile_name */
  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));

  /* APR doesn't like "" directories */
  if (base_dir[0] == '\0')
    base_dir_apr = ".";
  else
    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
  apr_err = apr_filepath_set(base_dir_apr, pool);
  if (apr_err)
    {
      return svn_error_wrap_apr
        (apr_err, _("Can't change working directory to '%s'"), base_dir);
    }

  /*** From here on, any problems that occur require us to cd back!! ***/

  /* Ask the working copy for a temporary file named FILENAME-something. */
  err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                   "" /* dirpath */,
                                   filename,
                                   ".tmp",
                                   svn_io_file_del_none, pool, pool);

  if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
    {
      const char *temp_dir_apr;

      svn_error_clear(err);

      SVN_ERR(svn_io_temp_dir(&base_dir, pool));

      SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
      apr_err = apr_filepath_set(temp_dir_apr, pool);
      if (apr_err)
        {
          return svn_error_wrap_apr
            (apr_err, _("Can't change working directory to '%s'"), base_dir);
        }

      err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                       "" /* dirpath */,
                                       filename,
                                       ".tmp",
                                       svn_io_file_del_none, pool, pool);
    }

  if (err)
    goto cleanup2;

  /*** From here on, any problems that occur require us to cleanup
       the file we just created!! ***/

  /* Dump initial CONTENTS to TMP_FILE. */
  apr_err = apr_file_write_full(tmp_file, translated_contents->data,
                                translated_contents->len, &written);

  apr_err2 = apr_file_close(tmp_file);
  if (! apr_err)
    apr_err = apr_err2;

  /* Make sure the whole CONTENTS were written, else return an error. */
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"),
                               tmpfile_name);
      goto cleanup;
    }

  err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool);
  if (err)
    goto cleanup;

  /* Get information about the temporary file before the user has
     been allowed to edit its contents. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Backdate the file a little bit in case the editor is very fast
     and doesn't change the size.  (Use two seconds, since some
     filesystems have coarse granularity.)  It's OK if this call
     fails, so we don't check its return value.*/
  apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool);

  /* Stat it again to get the mtime we actually set. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Prepare the editor command line.  */
  err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
  if (err)
    goto cleanup;
  cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);

  /* If the caller wants us to leave the file around, return the path
     of the file we'll use, and make a note not to destroy it.  */
  if (tmpfile_left)
    {
      *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
      remove_file = FALSE;
    }

  /* Now, run the editor command line.  */
  sys_err = system(cmd);
  if (sys_err != 0)
    {
      /* Extracting any meaning from sys_err is platform specific, so just
         use the raw value. */
      err =  svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
                               _("system('%s') returned %d"), cmd, sys_err);
      goto cleanup;
    }

  /* Get information about the temporary file after the assumed editing. */
  apr_err = apr_stat(&finfo_after, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* If the file looks changed... */
  if ((finfo_before.mtime != finfo_after.mtime) ||
      (finfo_before.size != finfo_after.size))
    {
      svn_stringbuf_t *edited_contents_s;
      err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
      if (err)
        goto cleanup;

      *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);

      /* Translate back to UTF8/LF if desired. */
      if (as_text)
        {
          err = svn_subst_translate_string2(edited_contents, FALSE, FALSE,
                                            *edited_contents, encoding, FALSE,
                                            pool, pool);
          if (err)
            {
              err = svn_error_quick_wrap
                (err,
                 _("Error normalizing edited contents to internal format"));
              goto cleanup;
            }
        }
    }
  else
    {
      /* No edits seem to have been made */
      *edited_contents = NULL;
    }

 cleanup:
  if (remove_file)
    {
      /* Remove the file from disk.  */
      err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool);

      /* Only report remove error if there was no previous error. */
      if (! err && err2)
        err = err2;
      else
        svn_error_clear(err2);
    }

 cleanup2:
  /* If we against all probability can't cd back, all further relative
     file references would be screwed up, so we have to abort. */
  apr_err = apr_filepath_set(old_cwd, pool);
  if (apr_err)
    {
      svn_handle_error2(svn_error_wrap_apr
                        (apr_err, _("Can't restore working directory")),
                        stderr, TRUE /* fatal */, "svn: ");
    }

  return svn_error_trace(err);
}
예제 #4
0
파일: target-test.c 프로젝트: vocho/openqnx
int main(int argc, char **argv)
{
  apr_pool_t *pool;
  svn_error_t *err;
  apr_array_header_t *targets;
  apr_array_header_t *condensed_targets;
  const char *common_path = 0;
  const char *common_path2 = 0;
  int i;

  if (argc < 2) {
    fprintf(stderr, "USAGE: %s <list of entries to be compared>\n", argv[0]);
    return EXIT_FAILURE;
  }

  /* Initialize the app. */
  if (svn_cmdline_init("target-test", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  /* Create our top-level pool. */
  pool = svn_pool_create(NULL);

  /* Create the target array */
  targets = apr_array_make(pool, argc - 1, sizeof(const char *));
  for (i = 1; i < argc; i++)
    {
      const char *path_utf8;
#ifndef AS400_UTF8
      err = svn_utf_cstring_to_utf8(&path_utf8, argv[i], pool);
#else
      /* Even when compiled with UTF support in V5R4, argv is still
       * encoded in ebcdic. */
      err = svn_utf_cstring_to_utf8_ex2(&path_utf8, argv[i],
                                        (const char *)0, pool);
#endif
      if (err != SVN_NO_ERROR)
        svn_handle_error2(err, stderr, TRUE, "target-test: ");
      APR_ARRAY_PUSH(targets, const char *) =
        svn_path_internal_style(path_utf8, pool);
    }


  /* Call the function */
  err = svn_path_condense_targets(&common_path, &condensed_targets, targets,
                                  TRUE, pool);
  if (err != SVN_NO_ERROR)
    svn_handle_error2(err, stderr, TRUE, "target-test: ");

  /* Display the results */
  {
    const char *common_path_stdout;
    err = svn_utf_cstring_from_utf8(&common_path_stdout, common_path, pool);
    if (err != SVN_NO_ERROR)
      svn_handle_error2(err, stderr, TRUE, "target-test: ");
    printf("%s: ", common_path_stdout);
  }
  for (i = 0; i < condensed_targets->nelts; i++)
    {
      const char * target = APR_ARRAY_IDX(condensed_targets, i, const char*);
      if (target)
        {
          const char *target_stdout;
          err = svn_utf_cstring_from_utf8(&target_stdout, target, pool);
          if (err != SVN_NO_ERROR)
            svn_handle_error2(err, stderr, TRUE, "target-test: ");
          printf("%s, ", target_stdout);
        }
      else
        printf("NULL, ");
    }
  printf("\n");

  /* Now ensure it works without the pbasename */
  err = svn_path_condense_targets(&common_path2, NULL, targets, TRUE, pool);
  if (err != SVN_NO_ERROR)
    svn_handle_error2(err, stderr, TRUE, "target-test: ");

  if (strcmp(common_path, common_path2) != 0)
    {
      printf("Common path without getting targets does not match common path "
             "with targets\n");
      return EXIT_FAILURE;
    }


  return EXIT_SUCCESS;
}