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