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 char *link_local;
00120
00121
00122 status=0;
00123 subpool=subsubpool=NULL;
00124
00125
00126 STOPIF( apr_pool_create_ex(&subpool, pool, NULL, NULL),
00127 "no pool");
00128
00129 STOPIF( ops__build_path( &path, cur_dir), NULL);
00130 DEBUGP("list of %s", path);
00131 STOPIF( hlp__local2utf8(path, &path_utf8, -1), NULL);
00132
00133 STOPIF_SVNERR( svn_ra_get_dir2,
00134 (current_url->session,
00135 &dirents, NULL, NULL,
00136
00137 (cur_dir->parent) ? path_utf8 + 2 : "",
00138 current_url->current_rev,
00139 SVN_DIRENT_HAS_PROPS | SVN_DIRENT_HAS_PROPS |
00140 SVN_DIRENT_KIND | SVN_DIRENT_SIZE,
00141 subpool));
00142
00143 for( hi=apr_hash_first(subpool, dirents); hi; hi = apr_hash_next(hi))
00144 {
00145 apr_hash_this(hi, &key, NULL, &kval);
00146 name=key;
00147 val=kval;
00148
00149
00150 STOPIF( cb__add_entry(cur_dir, name, NULL,
00151 NULL, 0, 0, NULL, 0, (void**)&sts), NULL);
00152
00153 if (url__current_has_precedence(sts->url) &&
00154 !S_ISDIR(sts->st.mode))
00155 {
00156
00157 sts->st.size=val->size;
00158
00159 decoder= sts->user_prop ?
00160 apr_hash_get(sts->user_prop,
00161 propval_updatepipe, APR_HASH_KEY_STRING) :
00162 NULL;
00163
00164 if (S_ISREG(sts->st.mode) && !decoder)
00165 {
00166
00167 }
00168 else if (S_ISREG(sts->st.mode) && val->size > 8192)
00169 {
00170
00171
00172 DEBUGP("file encoded, but too big for fetching (%llu)",
00173 (t_ull)val->size);
00174 }
00175 else
00176 {
00177
00178 STOPIF( url__full_url(sts, &url), NULL);
00179
00180
00181 STOPIF( apr_pool_create_ex(&subsubpool, subpool, NULL, NULL),
00182 "no pool");
00183
00184
00185
00186 STOPIF( rev__get_text_into_buffer(url, sts->repos_rev,
00187 decoder ? decoder->data : NULL,
00188 &entry_text, NULL, sts, NULL, subsubpool), NULL);
00189
00190 sts->st.size=entry_text->len;
00191 DEBUGP("parsing %s as %llu: %s", url,
00192 (t_ull)sts->st.size, entry_text->data);
00193
00194
00195
00196 if (!S_ISREG(sts->st.mode))
00197
00198 STOPIF( ops__string_to_dev(sts, entry_text->data, NULL), NULL);
00199
00200
00201
00202
00203 if (S_ISLNK(sts->st.mode))
00204 {
00205
00206
00207 STOPIF( hlp__utf82local(entry_text->data+strlen(link_spec),
00208 &link_local, -1), NULL);
00209 sts->st.size = strlen(link_local);
00210 }
00211
00212 if (subsubpool) apr_pool_destroy(subsubpool);
00213 }
00214
00215
00216 if (sts->user_prop)
00217 {
00218 apr_pool_destroy(apr_hash_get(sts->user_prop, "", 0));
00219 sts->user_prop=NULL;
00220 }
00221
00222 DEBUGP_dump_estat(sts);
00223 }
00224
00225
00226
00227 if (val->kind == svn_node_dir)
00228 {
00229 STOPIF( sync___recurse( sts, subpool), NULL);
00230 }
00231
00232 }
00233
00234 ex:
00235 if (subpool) apr_pool_destroy(subpool);
00236
00237 return status;
00238 }
00239
00240
00244 int sync__progress(struct estat *sts)
00245 {
00246 int status;
00247 struct sstat_t st;
00248 char *path;
00249
00250
00251 status=0;
00252 STOPIF( ops__build_path(&path, sts), NULL);
00253
00254 STOPIF( waa__delete_byext( path, WAA__FILE_MD5s_EXT, 1), NULL);
00255 STOPIF( waa__delete_byext( path, WAA__PROP_EXT, 1), NULL);
00256
00257
00258
00259
00260 sts->st.mode = (sts->st.mode & ~S_IFMT) |
00261 PACKED_to_MODE_T(sts->new_rev_mode_packed);
00262
00263
00264 STOPIF( st__rm_status(sts), NULL);
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 if ( hlp__lstat(path, &st) == 0 )
00295 {
00296 if ((sts->st.mode & S_IFMT) == 0)
00297 {
00298 sts->st=st;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 sts->st.ino=st.ino;
00308 sts->st.dev=st.dev;
00309 sts->st.size=st.size;
00310
00311
00312 sts->st.ctim=st.ctim;
00313
00314 if (!(sts->remote_status & FS_META_MTIME))
00315 sts->st.mtim=st.mtim;
00316 if (!(sts->remote_status & FS_META_OWNER))
00317 sts->st.uid=st.uid;
00318 if (!(sts->remote_status & FS_META_GROUP))
00319 sts->st.gid=st.gid;
00320 if (!(sts->remote_status & FS_META_UMODE))
00321 sts->st.mode=st.mode;
00322
00323
00324
00325 if (S_ISDIR(sts->st.mode))
00326 sts->flags |= RF_CHECK;
00327 }
00328 else
00329 {
00330 if (S_ISANYSPECIAL(sts->st.mode))
00331 {
00332
00333 sts->st.mode= (sts->st.mode & ~S_IFMT) | S_IFREG;
00334 }
00335 }
00336
00337
00338 if (S_ISDIR(sts->st.mode))
00339 sts->to_be_sorted=1;
00340
00341
00342 ex:
00343 return status;
00344 }
00345
00346
00350 int sync__work(struct estat *root, int argc, char *argv[])
00351 {
00352 int status;
00353 svn_error_t *status_svn;
00354 svn_revnum_t rev;
00355 char *strings;
00356 int string_space;
00357
00358
00359 status=0;
00360 status_svn=NULL;
00361 STOPIF( waa__find_base(root, &argc, &argv), NULL);
00362 STOPIF( url__load_nonempty_list(NULL, 0), NULL);
00363
00364
00365
00366
00367 string_space=0;
00368 strings=NULL;
00369 while ( ! ( status=url__iterator(&rev) ) )
00370 {
00371 if (opt__verbosity() > VERBOSITY_VERYQUIET)
00372 printf("sync-repos for %s rev\t%llu.\n",
00373 current_url->url, (t_ull)rev);
00374
00375
00376 current_url->current_rev=0;
00377 STOPIF( cb__record_changes(root, rev, current_url->pool), NULL);
00378
00379
00380 current_url->current_rev=rev;
00381 STOPIF( ci__set_revision(root, rev), NULL);
00382
00383 STOPIF( sync___recurse(root, current_url->pool), NULL);
00384 }
00385 STOPIF_CODE_ERR( status != EOF, status, NULL);
00386
00387
00388 STOPIF( hlp__lstat( ".", &root->st), NULL);
00389 root->flags |= RF_CHECK;
00390
00391
00392
00393
00394 STOPIF( waa__output_tree(root), NULL);
00395
00396 STOPIF( url__output_list(), NULL);
00397
00398 STOPIF( waa__delete_byext(wc_path, WAA__COPYFROM_EXT, 1), NULL);
00399
00400
00401 ex:
00402 STOP_HANDLE_SVNERR(status_svn);
00403 ex2:
00404 return status;
00405 }
00406