⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sites.c

📁 站点映像程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -