FreeBSD/contrib/subversion/subversion/libsvn_fs_fs/hotcopy.c
/* Like svn_io_copy_dir_recursively() but doesn't copy regular files that
 * exist in the destination and do not differ from the source in terms of
 * kind, size, and mtime. Set *SKIPPED_P to FALSE only if at least one
 * file was copied, do not change the value in *SKIPPED_P otherwise.
 * SKIPPED_P may be NULL if not required. */
Like svn_io_copy_dir_recursively() but doesn't copy regular files that
exist in the destination and do not differ from the source in terms of
kind, size, and mtime. Set *SKIPPED_P to FALSE only if at least one
file was copied, do not change the value in *SKIPPED_P otherwise.
SKIPPED_P may be NULL if not required.
Like svn_io_copy_dir_recursively () but doesn ' t copy regular files that exist in the destination and do not differ from the source in terms of kind size and mtime . Set * SKIPPED_P to FALSE only if at least one file was copied do not change the value in * SKIPPED_P otherwise . SKIPPED_P may be NULL if not required .
static svn_error_t *
hotcopy_io_copy_dir_recursively(svn_boolean_t *skipped_p,
                                const char *src,
                                const char *dst_parent,
                                const char *dst_basename,
                                svn_boolean_t copy_perms,
                                svn_cancel_func_t cancel_func,
                                void *cancel_baton,
                                apr_pool_t *pool)
{
  svn_node_kind_t kind;
  apr_status_t status;
  const char *dst_path;
  apr_dir_t *this_dir;
  apr_finfo_t this_entry;
  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
  apr_pool_t *subpool = svn_pool_create(pool);
  dst_path = svn_dirent_join(dst_parent, dst_basename, pool);
  SVN_ERR(svn_io_check_path(src, &kind, subpool));
  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("Source '%s' is not a directory"),
                             svn_dirent_local_style(src, pool));
  SVN_ERR(svn_io_check_path(dst_parent, &kind, subpool));
  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("Destination '%s' is not a directory"),
                             svn_dirent_local_style(dst_parent, pool));
  SVN_ERR(svn_io_check_path(dst_path, &kind, subpool));
  SVN_ERR(svn_io_make_dir_recursively(dst_path, pool));
  SVN_ERR(svn_io_dir_open(&this_dir, src, subpool));
  for (status = apr_dir_read(&this_entry, flags, this_dir);
       status == APR_SUCCESS;
       status = apr_dir_read(&this_entry, flags, this_dir))
    {
      if ((this_entry.name[0] == '.')
          && ((this_entry.name[1] == '\0')
              || ((this_entry.name[1] == '.')
                  && (this_entry.name[2] == '\0'))))
        {
          continue;
        }
      else
        {
          const char *entryname_utf8;
          if (cancel_func)
            SVN_ERR(cancel_func(cancel_baton));
          SVN_ERR(entry_name_to_utf8(&entryname_utf8, this_entry.name,
                                     src, subpool));
          if (this_entry.filetype == APR_REG) 
            {
              SVN_ERR(hotcopy_io_dir_file_copy(skipped_p, src, dst_path,
                                               entryname_utf8, subpool));
            }
          else if (this_entry.filetype == APR_LNK) 
            {
              const char *src_target = svn_dirent_join(src, entryname_utf8,
                                                       subpool);
              const char *dst_target = svn_dirent_join(dst_path,
                                                       entryname_utf8,
                                                       subpool);
              SVN_ERR(svn_io_copy_link(src_target, dst_target,
                                       subpool));
            }
          else if (this_entry.filetype == APR_DIR) 
            {
              const char *src_target;
              if (strcmp(src, dst_parent) == 0
                  && strcmp(entryname_utf8, dst_basename) == 0)
                continue;
              src_target = svn_dirent_join(src, entryname_utf8, subpool);
              SVN_ERR(hotcopy_io_copy_dir_recursively(skipped_p,
                                                      src_target,
                                                      dst_path,
                                                      entryname_utf8,
                                                      copy_perms,
                                                      cancel_func,
                                                      cancel_baton,
                                                      subpool));
            }
        }
    }
  if (! (APR_STATUS_IS_ENOENT(status)))
    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
                              svn_dirent_local_style(src, pool));
  status = apr_dir_close(this_dir);
  if (status)
    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
                              svn_dirent_local_style(src, pool));
  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}
static svn_error_t * hotcopy_io_copy_dir_recursively ( svn_boolean_t * skipped_p , const char * src , const char * dst_parent , const char * dst_basename , svn_boolean_t copy_perms , svn_cancel_func_t cancel_func , void * cancel_baton , apr_pool_t * pool ) { svn_node_kind_t kind ; apr_status_t status ; const char * dst_path ; apr_dir_t * this_dir ; apr_finfo_t this_entry ; apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME ; apr_pool_t * subpool = svn_pool_create ( pool ) ; dst_path = svn_dirent_join ( dst_parent , dst_basename , pool ) ; SVN_ERR ( svn_io_check_path ( src , & kind , subpool ) ) ; if ( kind != svn_node_dir ) return svn_error_createf ( SVN_ERR_NODE_UNEXPECTED_KIND , NULL , _ ( " " ) , svn_dirent_local_style ( src , pool ) ) ; SVN_ERR ( svn_io_check_path ( dst_parent , & kind , subpool ) ) ; if ( kind != svn_node_dir ) return svn_error_createf ( SVN_ERR_NODE_UNEXPECTED_KIND , NULL , _ ( " " ) , svn_dirent_local_style ( dst_parent , pool ) ) ; SVN_ERR ( svn_io_check_path ( dst_path , & kind , subpool ) ) ; SVN_ERR ( svn_io_make_dir_recursively ( dst_path , pool ) ) ; SVN_ERR ( svn_io_dir_open ( & this_dir , src , subpool ) ) ; for ( status = apr_dir_read ( & this_entry , flags , this_dir ) ; status == APR_SUCCESS ; status = apr_dir_read ( & this_entry , flags , this_dir ) ) { if ( ( this_entry . name [ 0 ] == ' ' ) && ( ( this_entry . name [ 1 ] == ' \0 ' ) || ( ( this_entry . name [ 1 ] == ' ' ) && ( this_entry . name [ 2 ] == ' \0 ' ) ) ) ) { continue ; } else { const char * entryname_utf8 ; if ( cancel_func ) SVN_ERR ( cancel_func ( cancel_baton ) ) ; SVN_ERR ( entry_name_to_utf8 ( & entryname_utf8 , this_entry . name , src , subpool ) ) ; if ( this_entry . filetype == APR_REG ) { SVN_ERR ( hotcopy_io_dir_file_copy ( skipped_p , src , dst_path , entryname_utf8 , subpool ) ) ; } else if ( this_entry . filetype == APR_LNK ) { const char * src_target = svn_dirent_join ( src , entryname_utf8 , subpool ) ; const char * dst_target = svn_dirent_join ( dst_path , entryname_utf8 , subpool ) ; SVN_ERR ( svn_io_copy_link ( src_target , dst_target , subpool ) ) ; } else if ( this_entry . filetype == APR_DIR ) { const char * src_target ; if ( strcmp ( src , dst_parent ) == 0 && strcmp ( entryname_utf8 , dst_basename ) == 0 ) continue ; src_target = svn_dirent_join ( src , entryname_utf8 , subpool ) ; SVN_ERR ( hotcopy_io_copy_dir_recursively ( skipped_p , src_target , dst_path , entryname_utf8 , copy_perms , cancel_func , cancel_baton , subpool ) ) ; } } } if ( ! ( APR_STATUS_IS_ENOENT ( status ) ) ) return svn_error_wrap_apr ( status , _ ( " " ) , svn_dirent_local_style ( src , pool ) ) ; status = apr_dir_close ( this_dir ) ; if ( status ) return svn_error_wrap_apr ( status , _ ( " " ) , svn_dirent_local_style ( src , pool ) ) ; svn_pool_destroy ( subpool ) ; return SVN_NO_ERROR ; }
Like svn_io_copy_dir_recursively() but doesn't copy regular files that
 exist in the destination and do not differ from the source in terms of
 kind, size, and mtime.
Like svn_io_copy_dir_recursively () but doesn ' t copy regular files that exist in the destination and do not differ from the source in terms of kind size and mtime .
/* Make a subpool for recursion */ /* The 'dst_path' is simply dst_parent/dst_basename */ /* Sanity checks:  SRC and DST_PARENT are directories, and
     DST_BASENAME doesn't already exist in DST_PARENT. */ /* Create the new directory. */ /* ### TODO: copy permissions (needs apr_file_attrs_get()) */ /* Loop over the dirents in SRC.  ('.' and '..' are auto-excluded) */ /* regular file */ /* symlink */ /* recurse */ /* Prevent infinite recursion by filtering off our
                 newly created destination path. */ /* ### support other APR node types someday?? */ /* Free any memory used by recursion */