?? sites.c
字號:
for( search=the_site->files; search!=NULL; search=search->next ) { if( search->diff != file_new ) continue; /* OK, we have us a new file... now iterate through the deleted * files and look for a match */ DEBUG( DEBUG_FILES, "- New file: %s\nComparing:", search->rel_local ); for( current=the_site->files; current!=NULL ; current=current->next ) { if( (current->diff != file_deleted) || current->dir ) { /* Ignore files which aren't deleted, and dirs, completely. * (search->diff==file_new, so we DON'T need to check * that current != search as well) */ continue; } DEBUG( DEBUG_FILES, " %s", current->rel_local ); if( (strcmp( search->filename, current->filename ) == 0) && current->remotesize == search->localsize && current->remotetime == search->localtime ) { DEBUG( DEBUG_FILES, " - matched!\n" ); break; } } if( current != NULL ) { /* OK, current == the deleted file, search == the new file. * First make sure search knows where it WAS before the move... */ search->old = current; /* Remove the deleted file from the list so it doesn't * actually get deleted by site_update */ file_delete( the_site, current ); /* Diddle the totals a bit */ search->diff = file_moved; the_site->numdeleted--; the_site->numnew--; the_site->nummoved++; } else { DEBUG( DEBUG_FILES, " - No match found.\n" ); } } DEBUG( DEBUG_FILES, "Finished checking for moved files.\n" );}/* This writes the remote files list back to the file * and has some hairy logic in the middle, but is otherwise * pretty simple. * TODO: This is crap. What we should really do is only * write out the remote file info, regardless... that is what the * info file is for. This would GREATLY simplify this entire function. * Would mean simply that in site_update, copying over the * modtimes + sizes. */#define WRITE_REMOTE_FILE( f ) \fprintf( fp, "%s\t%ld\t%ld\n", f->rel_remote, f->remotetime, f->remotesize );#define WRITE_LOCAL_FILE( f ) \fprintf( fp, "%s\t%ld\t%ld\n", f->rel_local, f->localtime, f->localsize );#define WRITE_REMOTE_LINK( f ) \fprintf( fp, "%s\t%s\t%s\n", f->rel_remote, LINKWORD, f->remotelink );#define WRITE_LOCAL_LINK( f ) \fprintf( fp, "%s\t%s\t%s\n", f->rel_local, LINKWORD, f->locallink );int site_writefiles( struct site_t *the_site ) { FILE *fp; struct site_file_t *current; fp = fopen( the_site->infofile, "w" ); if( fp == NULL ) { return -1; } for( current = the_site->files; current!=NULL; current=current->next ) { if( current->dir ) { if( current->updated ) { /* DIR: Updated */ switch( current->diff ) { case file_new: case file_unchanged: /* It's new, or it's already there... */ fprintf( fp, "%s\t%s\n", current->rel_local, DIRWORD ); break; case file_moved: /* invalid */ case file_changed: /* invalid */ case file_deleted:/* it's not there now */ default: break; } } else { /* DIR: Not Updated */ switch( current->diff ) { case file_unchanged: /* ... it was there anyway */ case file_deleted: /* ... but it wasn't deleted */ /* So the directory exists remotely */ fprintf( fp, "%s\t%s\n", current->rel_remote, DIRWORD ); break; case file_new: /* ... but it wasn't created */ default: /* So the directory does not exist remotely */ break; } } } else if( current->link ) { if( current->updated ) { /* LINK: Updated */ switch( current->diff ) { case file_new: /* it's there now */ case file_unchanged: /* it's still there now */ case file_changed: /* it's there now but differently */ WRITE_LOCAL_LINK( current ); break; case file_deleted: /* it's not there now */ default: break; } } else { /* LINK: Not Updated */ switch( current->diff ) { case file_unchanged: /* it's still there anyway */ case file_changed: /* it's still there anyway */ case file_deleted: /* but actually still there */ WRITE_REMOTE_LINK( current ); break; case file_new: /* it's not there */ default: break; } } } else { if( current->updated ) { /* FILE: Updated */ switch( current->diff ) { case file_unchanged: /* Write state of remote file */ WRITE_REMOTE_FILE( current ); break; case file_moved: case file_changed: case file_new: /* Write state of local file */ WRITE_LOCAL_FILE( current ); break; case file_deleted: /* So don't write anything out */ break; } } else { /* FILE: Not Updated */ switch( current->diff ) { case file_changed: /* ... but it hasn't been updated */ case file_unchanged: case file_deleted: /* ... but it hasn't been deleted */ /* Write out the remote time */ WRITE_REMOTE_FILE( current ); break; case file_moved: /* But it hasn't actually been moved, so write out * the 'deleted' file (where the moved file WAS), and * ignore the 'new' file (where it was moved TO) */ WRITE_REMOTE_FILE( current->old ); break; case file_new: /* So ignore it... */ break; } } } } fclose( fp ); return 0;}#undef WRITE_REMOTE_FILE#undef WRITE_LOCAL_FILE/* Simply marks all the files in the given site as 'updated'. * For 'dynamic updating', this will do, by diff== * file_deleted: Remove the file from the list * file_changed, file_new: Set diff=file_unchanged * file_moved: Remove the ->old, set diff=file_unchanged * file_unchanged: Do nothing. */void site_catchup( struct site_t *the_site ) { struct site_file_t *current; for( current=the_site->files; current!=NULL; current=current->next ) { current->updated = true; } /* Mark it as mirrored */ the_site->is_different = false;}/* Reinitializes the site - clears any remote files * from the list, and marks all other files as 'new locally'. */void site_initialize( struct site_t *the_site ) { struct site_file_t *current, *next; current = the_site->files; while( current!= NULL ) { next = current->next; switch( current->diff ) { case file_deleted: file_delete( the_site, current ); the_site->numdeleted--; break; case file_moved: /* Current is the NEW file, current->old is the DELETED * file. So, simply nuke current->old. */ current->old = NULL; current->updated = false; the_site->nummoved--; the_site->numnew++; current->diff = file_new; break; case file_changed: current->updated = false; the_site->numchanged--; the_site->numnew++; current->diff = file_new; break; case file_unchanged: current->updated = false; the_site->numunchanged--; the_site->numnew++; current->diff = file_new; break; case file_new: current->updated = false; break; } current = next; } if( the_site->files == NULL ) { /* There are no files remotely OR locally, so the * sites are the same */ the_site->is_different = false; } else { /* Otherwise, we KNOW that there are no files remotely * since we just removed them from memory, so any * remaining files must be local ones. Hence, the sites * ARE different */ the_site->is_different = true; }}/* This walks the files list as returned by the protocol driver, * and converts it into a 'real' files list. */void site_fetch_walk( struct site_t *the_site, struct proto_file_t *files ) { struct proto_file_t *this_file, *next_file; struct site_file_t *file; char rel_local[BUFSIZ]; /* temporary */ site_destroy( the_site ); this_file = files; while( this_file != NULL ) { /* Check whether the filename is excluded. Mock up a rel_local * for it. Bit noddy */ /* rel_local starts with a / */ rel_local[0] = '/'; rel_local[1] = '\0'; /* FIXME: Buffer ovverrun here. */ strcat( rel_local, this_file->directory ); strcat( rel_local, this_file->filename ); if( !file_isexcluded( this_file->filename, rel_local, the_site ) ) { /* Add the file to the list */ if( this_file->isdir ) { file = file_append( the_site ); } else { file = file_prepend( the_site ); } /* Pointer copy the filename and directory strings... nothing * to free out of this_file now. */ file->filename = this_file->filename; file->directory = this_file->directory; file->dir = this_file->isdir; /* Sort out the names */ site_assignnames( file, the_site ); file->diff = file_deleted; file->updated = false; /* ... so, it exists remotely only and hasn't been deleted. * bit of a hack, but okay for the moment... */ if( ! this_file->isdir ) { file->remotesize = this_file->size; file->remotetime = this_file->modtime; } fe_fetch_found( file ); } next_file = this_file->next; free( this_file ); this_file = next_file; }}/* Updates the remote file list... site_fetch_callback is called for * every remote file found. */int site_fetch( struct site_t *the_site ) { struct proto_file_t *files = NULL; int ret; if( CALL(fetch_list) == NULL ) { return SITE_UNIMPL; } ret = proto_init( the_site ); if( ret != SITE_OK ) return ret; ret = CALL(fetch_list)( the_site->remote_root, &files ); CALL(finish)( ); if( ret == PROTO_OK ) { /* Copy over the list of files */ site_fetch_walk( the_site, files ); return SITE_OK; } else { return SITE_FAILED; }}/* Destroys a file */void site_destroyfile( struct site_file_t *file ) { free( file->directory ); free( file->filename ); free( file->full_local ); free( file->full_remote ); free( file->rel_local ); free( file->rel_remote ); free( file );}/* Called to delete all the files associated with the site */void site_destroy( struct site_t *the_site ) { struct site_file_t *current, *next; current = the_site->files; while( current != NULL ) { next = current->next; if( current->old != NULL ) { site_destroyfile( current->old ); } site_destroyfile( current ); current = next; } the_site->files = NULL; the_site->files_tail = NULL;}/* Produces a section of the flat listing output, of all the items * with the given diff type in the given site, using the given section * name. */void site_flatlist_items( FILE *f, struct site_t *the_site, const enum file_diff diff, const char *name ) { struct site_file_t *current; fprintf( f, "sectstart|%s", name ); putc( '\n', f ); for( current = the_site->files; current!=NULL; current=current->next) { if( current->diff == diff ) { fprintf( f, "item|%s%s", current->rel_remote, current->dir?"/":"" ); if( current->old !=NULL ) { fprintf( f, "|%s\n", current->old->rel_remote ); } else { putc( '\n', f ); } } } fprintf( f, "sectend|%s\n", name );}/* Produce the flat listing output for the given site */void site_flatlist( FILE *f, struct site_t *the_site ) { fprintf( f, "sitestart|%s", the_site->name ); if( the_site->url ) fprintf( f, "|%s", the_site->url ); putc( '\n', f ); if( the_site->numnew > 0 ) site_flatlist_items( f, the_site, file_new, "added" ); if( the_site->numchanged > 0 ) site_flatlist_items( f, the_site, file_changed, "changed" ); if( the_site->numdeleted > 0 ) site_flatlist_items( f, the_site, file_deleted, "deleted" ); if( the_site->nummoved > 0 ) site_flatlist_items( f, the_site, file_moved, "moved" ); fprintf( f, "siteend|%s\n", the_site->is_different?"changed":"unchanged" );}const char *site_pseudourl( struct site_t *the_site ) { static char urlbuf[256]; snprintf( urlbuf, 256, "%s://%s%s", the_site->driver->service_name, the_site->server, the_site->remote_root_user + ( the_site->remote_isrel ? 1 : 0 ) ); return urlbuf;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -