?? sites.c
字號(hào):
if( ret != SITE_OK ) return ret; ret = site_synch_create_directories( the_site ); if( ret == 0 ) { ret = site_synch_files( the_site ); if( ret == 0 ) { ret = site_synch_remove_directories( the_site ); } } CALL(finish)( ); if( ret == 0 ) { return SITE_OK; } else { return SITE_ERRORS; }}static int site_update_create_directories( struct site_t *the_site, bool onlymarked) { struct site_file_t *current; int ret = 0; for( current=the_site->files; current!=NULL; current=current->next ) { if( onlymarked && !current->marked ) continue; if( current->dir && (current->diff == file_new ) ) { /* New dir! */ if( fe_prompting ) if( !fe_can_update( current ) ) continue; fe_updating( current ); if( CALL(dir_create)( current->full_remote ) != PROTO_OK ) { fe_updated( current, false, the_site->driver->last_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } } } return ret;}static int site_update_delete_files( struct site_t *the_site, bool onlymarked ) { struct site_file_t *current; int ret = 0; for( current=the_site->files; current!=NULL; current=current->next ) { if( onlymarked && !current->marked ) continue; /* Skip directories and links, and only do deleted files on * this pass */ if( (current->diff == file_deleted ) && !( current->dir || current->link ) ) { if( fe_prompting ) if( !fe_can_update( current ) ) break; fe_updating( current ); if( CALL(file_delete)( current->full_remote ) != PROTO_OK ) { fe_updated( current, false, the_site->driver->last_error ); ret = 1; } else { /* Successful update - file was deleted */ fe_updated( current, true, NULL ); current->updated = true; } } } return ret;}/* Does everything but file deletes */static int site_update_files( struct site_t *the_site, bool onlymarked ) { struct site_file_t *current; char *driver_error = the_site->driver->last_error; int ret = 0; DEBUG( DEBUG_SITES, "update_files entry.\n" ); for( current=the_site->files; current!=NULL; current=current->next ) { DEBUG( DEBUG_SITES, "loop start.\n" ); if( current->dir || current->link || (onlymarked && !current->marked) ) continue; switch( current->diff ) { case file_new: /* File is new, upload it */ DEBUG( DEBUG_SITES, "file_new.\n" ); if( fe_prompting ) if( !fe_can_update( current ) ) break; fe_updating( current ); if( CALL(file_upload)( current->full_local, current->full_remote, current->isascii ) != PROTO_OK ) { DEBUG( DEBUG_SITES, "file_upload failed.\n" ); fe_updated( current, false, driver_error ); ret = 1; } else { /* Successful upload... now we need to chmod it? */ DEBUG( DEBUG_SITES, "file_upload success.\n" ); if( (the_site->perms == sitep_all) || ( (current->mode & S_IXUSR) && (the_site->perms == sitep_exec) ) ) { /* We need to chmod the file ... */ if( CALL(file_chmod)( current->full_remote, current->mode ) != PROTO_OK ) { fe_updated( current, false, driver_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } } else { fe_updated( current, true, NULL ); current->updated = true; } } break; case file_changed: /* File has changed, upload it */ DEBUG( DEBUG_SITES, "file_changed.\n" ); if( fe_prompting ) if( !fe_can_update( current ) ) continue; if( the_site->nooverwrite ) { /* Must delete remote file before uploading new copy. * FIXME: Icky hack to convince the FE we are about to * delete the file */ current->diff = file_deleted; fe_updating( current ); if( CALL(file_delete)( current->full_remote ) != PROTO_OK ) { fe_updated( current, false, driver_error ); ret = 1; current->diff = file_changed; /* Don't upload it! */ break; } else { fe_updated( current, true, NULL ); current->diff = file_changed; } } fe_updating( current ); /* Now, upload it */ if( CALL(file_upload)( current->full_local, current->full_remote, current->isascii ) != PROTO_OK ) { fe_updated( current, false, driver_error ); ret = 1; } else { /* Successful upload... now we need to chmod it? */ if( (the_site->perms == sitep_all) || ( (current->mode & S_IXUSR) && (the_site->perms == sitep_exec) ) ) { /* We need to chmod the file ... */ if( CALL(file_chmod)( current->full_remote, current->mode ) != PROTO_OK ) { fe_updated( current, false, driver_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } } else { fe_updated( current, true, NULL ); current->updated = true; } } break; case file_moved: /* The file has been moved */ DEBUG( DEBUG_SITES, "file_moved.\n" ); if( fe_prompting ) { if( !fe_can_update( current ) ) break; } else { fe_updating( current ); } if( CALL(file_move)( current->old->full_remote, current->full_remote ) != PROTO_OK ) { ret = 1; fe_updated( current, false, driver_error ); } else { /* Successful update - file was moved */ current->updated = true; fe_updated( current, true, NULL ); } break; default: /* Ignore everything else */ DEBUG( DEBUG_SITES, "file ignored.\n" ); break; } DEBUG( DEBUG_SITES, "loop end.\n" ); } DEBUG( DEBUG_SITES, "update_files exit.\n" ); return ret; }static int site_update_delete_directories( struct site_t *the_site, bool onlymarked ){ struct site_file_t *current; int ret = 0; /* This one must iterate through the list BACKWARDS, so * directories are deleted bottom up */ for( current=the_site->files_tail; current!=NULL; current=current->prev ) { if( onlymarked && !current->marked ) continue; if( current->dir && (current->diff == file_deleted ) ) { if( fe_prompting ) if( !fe_can_update( current ) ) continue; fe_updating( current ); if( CALL(dir_remove)( current->full_remote ) != PROTO_OK ) { ret = 1; fe_updated( current, false, the_site->driver->last_error ); } else { /* Successful delete */ current->updated = true; fe_updated( current, true, NULL ); } } } return ret;}static int site_update_links( struct site_t *the_site, bool onlymarked ) { struct site_file_t *current; int ret = 0; for( current=the_site->files; current!=NULL; current=current->next ) { if( onlymarked && !current->marked ) continue; if( current->link ) { switch( current->diff ) { case file_new: fe_updating( current ); if( CALL(link_create)( current->full_remote, current->locallink ) != PROTO_OK ) { fe_updated( current, false, the_site->driver->last_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } break; case file_changed: fe_updating( current ); if( CALL(link_change)( current->full_remote, current->locallink ) != PROTO_OK ) { fe_updated( current, false, the_site->driver->last_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } break; case file_deleted: fe_updating( current ); if( CALL(link_delete)( current->full_remote ) != PROTO_OK ) { fe_updated( current, false, the_site->driver->last_error ); ret = 1; } else { fe_updated( current, true, NULL ); current->updated = true; } default: break; } } } return ret;}static int proto_init( struct site_t *the_site ) { /* TODO: Move the proto_host's into site_t */ struct proto_host_t server, proxy, *proxy_pass; int ret; ftp_use_passive = the_site->ftp_pasv_mode;#ifdef USE_DAV http_disable_expect = the_site->http_no_expect; http_conn_limit = the_site->http_limit;#endif server.hostname = the_site->server; server.port = the_site->port; server.username = the_site->username; server.password = the_site->password; proxy.hostname = the_site->proxy_server; proxy.port = the_site->proxy_port; proxy.username = the_site->username; proxy.password = the_site->password; if( the_site->proxy_server == NULL ) { proxy_pass = NULL; } else { proxy_pass = &proxy; } ret = CALL(init)( the_site->remote_root, &server, proxy_pass ); switch( ret ) { case PROTO_LOOKUP: ret = SITE_LOOKUP; break; case PROTO_CONNECT: ret = SITE_CONNECT; break; case PROTO_AUTH: ret = SITE_AUTH; break; default: ret = SITE_OK; break; } return ret;}/* Updates the remote site with the local copy. * This is the core functionality of sitecopy. * All we do is compare the local files list with the remote files * list, and upload any changed or new files. * Directories are treated differently - any new ones must be created BEFORE * any files are uploaded, and any old ones must be deleted AFTER any files * are deleted, since most FTP servers will not allow you to DELE a * non-empty directory. */int site_update( struct site_t *the_site, bool onlymarked ) { int ret = 0; ret = proto_init( the_site ); if( ret != SITE_OK ) return ret; ret = site_update_create_directories( the_site, onlymarked ); if( ret == 0 || site_keepgoing ) { /* Delete files first, since they might be quota-limited * on the remote site */ if( !the_site->nodelete ) { ret += site_update_delete_files( the_site, onlymarked ); } if( ret == 0 || site_keepgoing ) { ret += site_update_files( the_site, onlymarked ); if( (ret == 0 || site_keepgoing) && (the_site->symlinks == sitesym_maintain ) ) { ret += site_update_links( the_site, onlymarked ); } if( (ret == 0 || site_keepgoing) && !the_site->nodelete ) { ret += site_update_delete_directories( the_site, onlymarked ); } } } CALL(finish)( ); if( ret == 0 ) { /* Site updated successfully. * Mark the site as 'unchanged' so, in a GUI FE, they * don't try and update it again. Hopefully. */ the_site->is_different = false; return SITE_OK; } else { /* Update not totally successfull */ return SITE_ERRORS; }}/* This populates the additional names in the site_file_t struct given, * using information in the given site */void site_assignnames( struct site_file_t *the_file, struct site_t *the_site ){ the_file->full_remote = malloc( strlen(the_site->remote_root) + strlen(the_file->directory) + strlen(the_file->filename) + 1 ); the_file->full_local = malloc( strlen(the_site->local_root) + strlen(the_file->directory) + strlen(the_file->filename) + 1 ); the_file->rel_local = malloc( strlen(the_file->directory) + strlen(the_file->filename) + 2 ); the_file->rel_remote = malloc( strlen(the_file->directory) + strlen(the_file->filename) + 2 ); strcpy( the_file->full_remote, the_site->remote_root ); strcat( the_file->full_remote, the_file->directory ); strcat( the_file->full_remote, the_file->filename ); strcpy( the_file->full_local, the_site->local_root ); strcat( the_file->full_local, the_file->directory ); strcat( the_file->full_local, the_file->filename ); strcpy( the_file->rel_local, "/" ); strcat( the_file->rel_local, the_file->directory ); strcat( the_file->rel_local, the_file->filename ); strcpy( the_file->rel_remote, "/" ); strcat( the_file->rel_remote, the_file->directory ); strcat( the_file->rel_remote, the_file->filename );}/* This reads off the remote files and the local files */int site_readfiles( struct site_t *the_site ) { if( site_readremotefiles( the_site ) < 0 ) return -1; if( site_readlocalfiles( the_site ) ) return -2; /* Check for moved files - compare new files with deleted ones */ if( the_site->checkmoved ) { site_checkmoved( the_site ); } /* Summing up... */ if( (the_site->numchanged + the_site->nummoved + the_site->numnew + (the_site->nodelete?0:the_site->numdeleted) ) > 0 ) { the_site->is_different = true; } else { the_site->is_different = false; } return 0;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -