00001
00002
00003
00004
00005
00006
00007
00008
00064 #include <apr_md5.h>
00065 #include <apr_pools.h>
00066 #include <apr_user.h>
00067 #include <apr_file_io.h>
00068 #include <subversion-1/svn_delta.h>
00069 #include <subversion-1/svn_ra.h>
00070 #include <subversion-1/svn_error.h>
00071 #include <subversion-1/svn_string.h>
00072 #include <subversion-1/svn_time.h>
00073
00074 #include <sys/types.h>
00075 #include <unistd.h>
00076 #include <ctype.h>
00077 #include <time.h>
00078 #include <fcntl.h>
00079
00080
00081 #include "global.h"
00082 #include "status.h"
00083 #include "checksum.h"
00084 #include "est_ops.h"
00085 #include "cache.h"
00086 #include "revert.h"
00087 #include "props.h"
00088 #include "commit.h"
00089 #include "waa.h"
00090 #include "url.h"
00091 #include "status.h"
00092 #include "update.h"
00093 #include "racallback.h"
00094 #include "helper.h"
00095
00096
00102 int sync___recurse(struct estat *cur_dir,
00103 apr_pool_t *pool)
00104 {
00105 int status;
00106 svn_error_t *status_svn;
00107 apr_pool_t *subpool, *subsubpool;
00108 apr_hash_t *dirents;
00109 char *path;
00110 const char *name;
00111 const void *key;
00112 void *kval;
00113 apr_hash_index_t *hi;
00114 svn_dirent_t *val;
00115 char *url, *path_utf8;
00116 struct svn_string_t *decoder;
00117 struct estat *sts;
00118 svn_stringbuf_t *entry_text;
00119
00120
00121 status=0;
00122 subpool=subsubpool=NULL;
00123
00124
00125 STOPIF( apr_pool_create_ex(&subpool, pool, NULL, NULL),
00126 "no pool");
00127
00128 STOPIF( ops__build_path( &path, cur_dir), NULL);
00129 DEBUGP("list of %s", path);
00130 STOPIF( hlp__local2utf8(path, &path_utf8, -1), NULL);
00131
00132 STOPIF_SVNERR( svn_ra_get_dir2,
00133 (current_url->session,
00134 &dirents, NULL, NULL,
00135
00136 (cur_dir->parent) ? path_utf8 + 2 : "",
00137 current_url->current_rev,
00138 SVN_DIRENT_HAS_PROPS | SVN_DIRENT_HAS_PROPS |
00139 SVN_DIRENT_KIND | SVN_DIRENT_SIZE,
00140 subpool));
00141
00142 for( hi=apr_hash_first(subpool, dirents); hi; hi = apr_hash_next(hi))
00143 {
00144 apr_hash_this(hi, &key, NULL, &kval);
00145 name=key;
00146 val=kval;
00147
00148
00149 STOPIF( cb__add_entry(cur_dir, name, NULL,
00150 NULL, 0, 0, NULL, 0, (void**)&sts), NULL);
00151
00152 if (url__current_has_precedence(sts->url) &&
00153 !S_ISDIR(sts->st.mode))
00154 {
00155
00156 sts->st.size=val->size;
00157
00158 decoder= sts->user_prop ?
00159 apr_hash_get(sts->user_prop,
00160 propval_updatepipe, APR_HASH_KEY_STRING) :
00161 NULL;
00162
00163 if (S_ISREG(sts->st.mode) && !decoder)
00164 {
00165
00166 }
00167 else if (S_ISREG(sts->st.mode) && val->size > 8192)
00168 {
00169
00170
00171 DEBUGP("file encoded, but too big for fetching (%llu)",
00172 (t_ull)val->size);
00173 }
00174 else
00175 {
00176
00177 STOPIF( url__full_url(sts, &url), NULL);
00178
00179
00180 STOPIF( apr_pool_create_ex(&subsubpool, subpool, NULL, NULL),
00181 "no pool");
00182
00183
00184
00185 STOPIF( rev__get_text_into_buffer(url, sts->repos_rev,
00186 decoder ? decoder->data : NULL,
00187 &entry_text, NULL, sts, NULL, subsubpool), NULL);
00188
00189 sts->st.size=entry_text->len;
00190 DEBUGP("parsing %s as %llu: %s", url,
00191 (t_ull)sts->st.size, entry_text->data);
00192
00193
00194
00195 if (!S_ISREG(sts->st.mode))
00196
00197 STOPIF( ops__string_to_dev(sts, entry_text->data, NULL), NULL);
00198
00199
00200
00201
00202 if (S_ISLNK(sts->st.mode))
00203 sts->st.size-=strlen(link_spec);
00204
00205 if (subsubpool) apr_pool_destroy(subsubpool);
00206 }
00207
00208
00209 if (sts->user_prop)
00210 {
00211 apr_pool_destroy(apr_hash_get(sts->user_prop, "", 0));
00212 sts->user_prop=NULL;
00213 }
00214
00215 DEBUGP_dump_estat(sts);
00216 }
00217
00218
00219
00220 if (val->kind == svn_node_dir)
00221 {
00222 STOPIF( sync___recurse( sts, subpool), NULL);
00223 }
00224
00225 }
00226
00227 ex:
00228 if (subpool) apr_pool_destroy(subpool);
00229
00230 return status;
00231 }
00232
00233
00237 int sync__progress(struct estat *sts)
00238 {
00239 int status;
00240 struct sstat_t st;
00241 char *path;
00242
00243
00244 status=0;
00245 STOPIF( ops__build_path(&path, sts), NULL);
00246
00247 STOPIF( waa__delete_byext( path, WAA__FILE_MD5s_EXT, 1), NULL);
00248 STOPIF( waa__delete_byext( path, WAA__PROP_EXT, 1), NULL);
00249
00250
00251
00252
00253 sts->st.mode = (sts->st.mode & ~S_IFMT) |
00254 PACKED_to_MODE_T(sts->new_rev_mode_packed);
00255
00256
00257 STOPIF( st__rm_status(sts), NULL);
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 if ( hlp__lstat(path, &st) == 0 )
00288 {
00289 if ((sts->st.mode & S_IFMT) == 0)
00290 {
00291 sts->st=st;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 sts->st.ino=st.ino;
00301 sts->st.dev=st.dev;
00302 sts->st.size=st.size;
00303
00304
00305 sts->st.ctim=st.ctim;
00306
00307 if (!(sts->remote_status & FS_META_MTIME))
00308 sts->st.mtim=st.mtim;
00309 if (!(sts->remote_status & FS_META_OWNER))
00310 sts->st.uid=st.uid;
00311 if (!(sts->remote_status & FS_META_GROUP))
00312 sts->st.gid=st.gid;
00313 if (!(sts->remote_status & FS_META_UMODE))
00314 sts->st.mode=st.mode;
00315
00316
00317
00318 if (S_ISDIR(sts->st.mode))
00319 sts->flags |= RF_CHECK;
00320 }
00321 else
00322 {
00323 if (S_ISANYSPECIAL(sts->st.mode))
00324 {
00325
00326 sts->st.mode= (sts->st.mode & ~S_IFMT) | S_IFREG;
00327 }
00328 }
00329
00330
00331 if (S_ISDIR(sts->st.mode))
00332 sts->to_be_sorted=1;
00333
00334
00335 ex:
00336 return status;
00337 }
00338
00339
00343 int sync__work(struct estat *root, int argc, char *argv[])
00344 {
00345 int status;
00346 svn_error_t *status_svn;
00347 svn_revnum_t rev;
00348 char *strings;
00349 int string_space;
00350
00351
00352 status=0;
00353 status_svn=NULL;
00354 STOPIF( waa__find_base(root, &argc, &argv), NULL);
00355 STOPIF( url__load_nonempty_list(NULL, 0), NULL);
00356
00357
00358
00359
00360 string_space=0;
00361 strings=NULL;
00362 while ( ! ( status=url__iterator(&rev) ) )
00363 {
00364 if (opt__get_int(OPT__VERBOSE) > VERBOSITY_VERYQUIET)
00365 printf("sync-repos for %s rev\t%llu.\n",
00366 current_url->url, (t_ull)rev);
00367
00368
00369 current_url->current_rev=0;
00370 STOPIF( cb__record_changes(root, rev, global_pool), NULL);
00371
00372
00373 current_url->current_rev=rev;
00374 STOPIF( ci__set_revision(root, rev), NULL);
00375
00376 STOPIF( sync___recurse(root, current_url->pool), NULL);
00377 }
00378 STOPIF_CODE_ERR( status != EOF, status, NULL);
00379
00380
00381 STOPIF( hlp__lstat( ".", &root->st), NULL);
00382 root->flags |= RF_CHECK;
00383
00384
00385
00386
00387 STOPIF( waa__output_tree(root), NULL);
00388
00389 STOPIF( url__output_list(), NULL);
00390
00391 STOPIF( waa__delete_byext(wc_path, WAA__COPYFROM_EXT, 1), NULL);
00392
00393
00394 ex:
00395 STOP_HANDLE_SVNERR(status_svn);
00396 ex2:
00397 return status;
00398 }
00399