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

📄 sites.c

📁 站点映像程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    sitecopy, for managing remote web sites.   Copyright (C) 1998-99, Joe Orton <joe@orton.demon.co.uk>                                                                        This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.     This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.     You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   $Id: sites.c,v 1.34.2.17 1999/08/27 17:48:58 joe Exp $*//* This is the core functionality of sitecopy, performing updates * and checking files etc. */#include <config.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <dirent.h>#include <fnmatch.h>#include <fcntl.h>#include <stdio.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <time.h>#include <utime.h>#ifndef HAVE_SNPRINTF#include <snprintf.h>#endif /* !HAVE_SNPRINTF */#include <basename.h>#include "common.h"#include "dirname.h"#include "frontend.h"#include "protocol.h"#include "socket.h"#include "sites.h"#include "ftp.h"/* The protocol drivers */const struct proto_driver ftp_driver = {    ftp_init,    ftp_finish,    ftp_move,    ftp_put,    ftp_get,    ftp_delete,    ftp_chmod,    ftp_mkdir,    ftp_rmdir,    NULL, /* create link */    NULL, /* change link target */    NULL, /* delete link */    ftp_fetch,    "ftp", /* service name */    21, /* service number */    "FTP",    ftp_error};#ifdef USE_DAV#include "httpdav.h"const struct proto_driver dav_driver = {    http_init, /* Connect */    http_finish, /* Disconnect */    dav_move, /* File move */    http_put, /* File upload - HTTP PUT */    http_get, /* File download */    http_delete, /* File delete */    NULL, /* File chmod... this could be done using either	   *   a) A special live property	   *   b) The ACL extensions: draft-ietf-webdav-acl-??.txt	   */    dav_mkcol, /* Dir create */    dav_rmdir, /* Dir remove, same as file remove */    dav_mkref, /* Create link */    dav_chref, /* Change link */    dav_rmref, /* Remove link */    /* fetch listing */#ifdef HAVE_LIBEXPAT    dav_fetch, #else    NULL, #endif    "http", /* Service name */    80, /* server number */    "WebDAV", /* User-visible protocol name */    http_error};#endif/* This is the maximum number of directories which can be held in the queue  * at one time - each entry is only a pointer, so the size is not too * much of a problem.  */#define MAXDIRS 500/* This is the string used in the storage files to indicate the * line is a directory rather than a file */#define DIRWORD "dir"/* And this is used for links */#define LINKWORD "link"/* Shorthand for protocol driver methods */#define CALL( a ) (*the_site->driver->a)/* This holds ALL the sites defined in the rcfile */struct site_t *all_sites; bool fe_prompting;bool site_keepgoing;static int proto_init( struct site_t *the_site );/* Prototypes */static void site_checkmoved( struct site_t *any_site );static void site_destroyfile( struct site_file_t *file );static int site_synch_create_directories( struct site_t *the_site );static int site_synch_files( struct site_t *the_site );static int site_synch_remove_directories( struct site_t *the_site );static int site_update_create_directories( struct site_t *the_site, bool onlymarked );static int site_update_delete_directories( struct site_t *the_site, bool onlymarked );static int site_update_delete_files( struct site_t *the_site, bool onlymarked );static int site_update_files( struct site_t *the_site, bool onlymarked );static int site_update_links( struct site_t *the_site, bool onlymarked );static void site_fetch_walk( struct site_t *the_site,		      struct proto_file_t *files );static int site_readlocalfiles( struct site_t * );static int site_readremotefiles( struct site_t * );static void site_flatlist_items( FILE *f, struct site_t *the_site, 			  const enum file_diff diff, const char *name );/* Assigns the _local and _remote filenames to the site file */static void site_assignnames( struct site_file_t *the_file, struct site_t *the_site );/* Functions for manipulating the doubly linked files list */static void file_delete( struct site_t *site, struct site_file_t *item );static struct site_file_t *file_prepend( struct site_t *site );static struct site_file_t *file_append( struct site_t *site );static struct site_file_t *file_create( void );/* Whether a file is excluded from the site or not */static bool file_isexcluded( const char *filename, const char *fullpath, 		      struct site_t *site );/* Whether a file is ASCII text or binary */static bool file_isascii( char *filename, struct site_t *site );/* Creates and initializes a file. * Returns NULL if out-of-memory */inline struct site_file_t *file_create( void ) {    struct site_file_t *file;    file = malloc( sizeof(struct site_file_t) );    if( file!=NULL ) {	/* Initialize */	memset( file, 0, sizeof(struct site_file_t) );    }    return file;}/* Creates a file prepended on to the beginning of the site files list. * Returns NULL if the file could not be malloc'ed. */struct site_file_t *file_prepend( struct site_t *site ) {    struct site_file_t *file;    file = file_create();    if( file == NULL ) return NULL;    if( site->files == NULL ) {	/* Empty list */	site->files = file;	site->files_tail = file;    } else {	/* Non-empty list... update pointers */	site->files->prev = file;	file->next = site->files;	site->files = file;    }    return file;}/* Deletes the given file from the given site */void file_delete( struct site_t *site, struct site_file_t *item ) {    if( item->prev ) {	/* Not first in list */	item->prev->next = item->next;    } else {	/* Not last in list */	site->files = item->next;    }    if( item->next ) {	/* Not last in list */	item->next->prev = item->prev;    } else {	/* Last in list */	site->files_tail = item->prev;    }    /* Safety */    item->prev = NULL;    item->next = NULL;}/* Creates a file added on to the end of the site files list. * Returns NULL if the file could not be malloc'ed. */struct site_file_t *file_append( struct site_t *site ) {    struct site_file_t *file;    file = file_create();    if( file == NULL ) return NULL;    if( site->files_tail == NULL ) {	/* Empty list */	site->files = file;	site->files_tail = file;    } else {	/* Non-empty list... update pointers */	site->files_tail->next = file;	file->prev = site->files_tail;	site->files_tail = file;    }    return file;}/* Returns whether the given filename is excluded from the * given site */bool file_isexcluded( const char *filename, const char *fullpath, 		      struct site_t *site ) {    struct exclude_t *excl;    DEBUG( DEBUG_FILES, "\nChecking excludes:\n" );    for( excl=site->excludes; excl != NULL; excl=excl->next ) {	DEBUG( DEBUG_FILES, "%s ", excl->pattern );	if( excl->haspath ) {	    if( fnmatch( excl->pattern, fullpath, FNM_PATHNAME ) == 0 )		break;	} else {	    if( fnmatch( excl->pattern, filename, 0 ) == 0 )		break;	}    }    if( excl != NULL ) { /* excluded */	DEBUG( DEBUG_FILES, "- matched\n" );	return true;    } else {	DEBUG( DEBUG_FILES, "... not matched.\n" );	return false;    }}bool file_isascii( char *filename, struct site_t *site ) {    int n;    DEBUG( DEBUG_FILES, "\nChecking ASCII list:\n" );    for( n=0; n != site->numascii; n++ ) {	DEBUG( DEBUG_FILES, "%s ", site->ascii[n] );	if( fnmatch( site->ascii[n], filename, 0 ) == 0 )	    break;    }    if( n < site->numascii ) { 	DEBUG( DEBUG_FILES, "- matched\n" );	return true;    } else {	DEBUG( DEBUG_FILES, "... not matched.\n" );	return false;    }}struct site_t *site_find( const char *sitename ) {    struct site_t *current;    for( current = all_sites; current!=NULL; current=current->next ) {	if( strcmp( current->name, sitename ) == 0 ) {	    /* We found it */	    return current;	}    }    return NULL;}static int site_synch_create_directories( struct site_t *the_site ) {    struct site_file_t *current;    int ret;        ret = 0;        for( current=the_site->files; current!=NULL; current=current->next ) {	if( current->dir && current->diff==file_deleted ) {	    fe_synching( current );	    if( mkdir( current->full_local, 0755 ) == 0 ) {		fe_synched( current, true, NULL );	    } else {		ret = 1;		fe_synched( current, false, strerror(errno) );	    }	}    }    return ret;}static int site_synch_files( struct site_t *the_site ) {    struct site_file_t *current;    struct utimbuf times;    int ret;    ret = 0;    for( current = the_site->files; current!=NULL; current=current->next ) {	if( current->dir ) continue;	switch( current->diff ) {	case file_changed:	case file_deleted:	    fe_synching( current );	    if( CALL(file_download)( current->full_local,current->full_remote,				     current->remotesize, current->isascii )		!= PROTO_OK ) {		fe_synched( current, false, the_site->driver->last_error );		ret = 2;	    } else {		/* Change the modtime of the local file so it doesn't look		 * like it's changed already */		times.actime = current->remotetime;		times.modtime = current->remotetime;		if( utime( current->full_local, &times ) < 0 ) {		    fe_synched( current, false, strerror(errno) );		    ret = 2;		} else {		    fe_synched( current, true, NULL );		}	    }	    break;	case file_new:	    fe_synching( current );	    if( unlink( current->full_local ) != 0 ) {		fe_synched( current, false, strerror(errno) );		ret = 2;	    } else {		fe_synched( current, true, NULL );	    }	    break;	case file_moved:	    fe_synching( current );	    if( rename( current->full_local, 			current->old->full_local ) == 0 ) {		fe_synched( current, true, NULL );	    } else {		fe_synched( current, false, strerror(errno) );		ret = 2;	    }	default:	    break;	    	}    }    return ret;}static int site_synch_remove_directories( struct site_t *the_site ) {    struct site_file_t *current;    int ret;    ret = 0;    for( current=the_site->files_tail; current!=NULL; current=current->prev ) {	if( current->dir && (current->diff==file_new) ) {	    fe_synching( current );	    if( rmdir( current->full_local ) == -1 ) {		fe_synched( current, false, strerror(errno) );		ret = 3;	    } else {		fe_synched( current, true, NULL );	    }	}    }    return ret;}/* Resyncs the LOCAL site with the REMOTE site. * This is site_update backwards, and is essentially the same in structure, * except with the logic reversed. */int site_synch( struct site_t *the_site ) {    int ret;    ret = proto_init( the_site );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -