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

📄 sites.c

📁 站点映像程序
💻 C
📖 第 1 页 / 共 4 页
字号:
int site_readremotefiles( struct site_t *the_site ) {    FILE *fp;    char buf[BUFSIZ], /* for the line */	tmp[BUFSIZ], /* for the current field */	*pos, /* for the current position within buf */	*point, /* for the curpos within tmp */	*this_file = NULL;    struct site_file_t *current;    size_t dir_length;    int state;    /* Get the remote files from the storage file */    DEBUG( DEBUG_FILES, "Reading info file: %s\n", the_site->infofile );    fp = fopen( the_site->infofile, "r" );    if( fp == NULL ) {	/* This is not an error condition, since the info file WILL NOT 	 * exist until the site has been created, which is okay, just means	 * there are 'no' files on the remote site */	return 1;    }    /* The file exists, so read it.     * Format: one item / line, tab-separated fields.     * First field is filename of item.     * Second field is 'dir' for directory items, or mtime for files     * Third field (files only) is size of file */    current = NULL;    while( fgets( buf, BUFSIZ, fp) != NULL ) {	/* Create a new file item and lob it on the end of the linked 	 * list */	current = file_append( the_site );	/* Make sure we have an end-of-buffer */	buf[BUFSIZ-1] = '\0';	this_file = NULL;	/* Now parse the line. Simple DFA, states are:	 *  0: Reading filename, field 1	 *  1: Reading date/time stamp or DIRWORD, field 2	 *  2: Reading file size, field 3 (if file)	 *  3: Junk state - consume-all-crud-till-end-of-line.	 * 	 * We read the current field into tmp char by char.	 * point is the current point within tmp. */	state = 0;	point = tmp;	for( pos = buf; *pos!='\0'; pos++ ) {	    if( *pos < 0 ) state = 5;	    switch( state ) {	    case 0:		if( *pos == '\t' ) {		    /* End of the filename */		    *point = '\0';		    this_file = strdup( tmp );		    point = tmp;		    state = 1;		} else {		    /* Still in the filename */		    *(point++) = *pos;		}		break;	    case 1:		if( *pos == '\t' || *pos == '\n' ) {		    /* End of the second field */		    *point = '\0';		    if( strlen( tmp ) > 0 ) {			if( strcmp( tmp, DIRWORD ) == 0 ) {			    /* It's a directory! */			    current->dir = true;			    state = 3; /* that's all we need */			} else if( strcmp( tmp, LINKWORD ) == 0 ) {			    current->link = true;			    point = tmp;			    state = 4; /* read the link target */			} else {			    /* It's a file! - field 2 is the mtime */			    current->dir = false;			    current->remotetime = atol( tmp );			    point = tmp;			    state = 2;			}		    } else {			/* Corrupt line, we need at least two fields */			/* FIXME: Report this to the user. */			state = 5;		    }					} else {		    /* Within the second field */		    *(point++) = *pos;		}		break;	    case 2:		if( *pos == '\n' ) {		    /* End of the size field */		    *point = '\0';		    current->remotesize = atol( tmp );		    state = 3;		} else {		    /* Within the file size field */		    *(point++) = *pos;		}		break;	    case 3: /* junk state */		break;	    case 4: /* read the link name */		if( *pos == '\n' ) {		    /* End of the field */		    *point = '\0';		    current->remotelink = strdup( tmp );		    state = 3;		} else {		    *(point++) = *pos;		}	    case 5: /* error state */		break;	    }	}	if( this_file==NULL || state == 5 ) {	    /* FIXME: Report this to the user */	    DEBUG( DEBUG_FILES, "Corrupt line.\n" );	    file_delete( the_site, current );	    continue;	}	current->diff = file_deleted;	current->filename = strdup( base_name( this_file ) );	/* we are going to chop the leading / of this_file */	if( strlen(current->filename) > strlen(this_file) ) {	    /* FIXME: Handle these errors properly */	    DEBUG( DEBUG_FILES, "Very corrupt line.\n" );	    free( current->filename );	    file_delete( the_site, current );	    continue;	}	dir_length = strlen(this_file) - strlen(current->filename ) - 1;	current->directory = malloc( dir_length + 1 );	strncpy( current->directory, this_file + 1, dir_length );	*(current->directory+dir_length) = '\0'; /* null-term */	DEBUG( DEBUG_FILES, "Split %s is: Dir [%s], name [%s]\n",	       this_file, current->directory, current->filename );	the_site->numdeleted++;	site_assignnames( current, the_site );	DEBUG( DEBUG_FILES, "Remote: [%s] - file: size: %ld  time: %ld\n",	       current->filename, current->remotesize, current->remotetime );	DEBUG( DEBUG_FILES, 	       "Directory: [%s]  Filename: %s\n"	       "rel_local: %s  rel_remote: %s\n"	       "full_local: %s  full_remote: %s\n",	       current->directory, current->filename,	       current->rel_local, current->rel_remote, 	       current->full_local, current->full_remote );	free( this_file );    }    fclose( fp );    return 0;}/* Read the local site files...  * A stack is used for directories within the site - this is not recursive. * Each item on the stack is a FULL PATH to the directory, i.e., including * the local site root. */int site_readlocalfiles( struct site_t *the_site ) {    char *dirstack[MAXDIRS], *this;    char *full = NULL, *fname, *temp;    struct stat item;    DIR *curdir;    struct dirent *ent;    int dirtop = 0;    size_t dir_length;    struct site_file_t *current;    /* Push the root directory on to the stack */    dirstack[dirtop++] = strdup( the_site->local_root );        /* Now, for all items in the stack, process all the files, and     * add the dirs to the stack. Everything we put on the stack is     * temporary and gets freed eventually. */    while( dirtop > 0 ) {	/* Pop the stack */	this = dirstack[--dirtop];		DEBUG( DEBUG_FILES, "Dir: %s\n", this );	curdir = opendir( this );	if( curdir == NULL ) {	    free( this );	    continue;	}	/* Now read all the directory entries */	while( (ent = readdir( curdir )) != NULL ) {	    if( full != NULL ) 		free( full );	    full = malloc( strlen( this ) + strlen( ent->d_name ) + 1 );	    strcpy( full, this );	    strcat( full, ent->d_name );	    DEBUG( DEBUG_FILES, "Item: %s - ", ent->d_name );#ifndef __EMX__ 	    if( lstat( full, &item ) == -1 ) {#else	    /* There are no symlinks under OS/2, use stat() instead */	    if( stat( full, &item ) == -1 ) {#endif		/* FIXME: FE warning here */		continue;	    }#ifndef __EMX__	    /* Is this a symlink? */	    if( S_ISLNK( item.st_mode ) ) {		DEBUG( DEBUG_FILES, "symlink - " );		if( the_site->symlinks == sitesym_ignore ) {		    /* Just skip it */		    DEBUG( DEBUG_FILES, "ignoring.\n" );		    continue;		} else if( the_site->symlinks == sitesym_follow ) {		    DEBUG( DEBUG_FILES, "followed - " );		    /* Else, carry on as normal, stat the real file */		    if( stat( full, &item ) == -1 ) {			/* It's probably a broken link */			DEBUG( DEBUG_FILES, "broken.\n" );			continue;		    }		} else {		    DEBUG( DEBUG_FILES, "maintained:\n" );		}	    }#endif /* __EMX__ */	    /* Now process it */	    /* This is the rel_local of this file - i.e., everything	     * apart from the local root */	    fname = (char *)full+strlen(the_site->local_root)-1;	    /* Check for excludes */	    if( file_isexcluded( ent->d_name, fname, the_site ) )		continue;   	    for( current=the_site->files; current!=NULL; current=current->next ) {		if( strcmp( current->rel_local, fname ) == 0 )		    /* Match found! */		    break;/*		last = current; */	    }	    	    if( S_ISREG( item.st_mode ) ) {		DEBUG( DEBUG_FILES, "file - " );		if( current == NULL ) {		    /* This is a new local file... */		    DEBUG( DEBUG_FILES, "new - " );		    the_site->numnew++;		    /* Add a new file to the beginning of the list */		    current = file_prepend( the_site );		    current->filename = strdup( base_name( fname ) );		    /* This is the length of the directory name...		     * fname = "/full/file/name.ext", filename = "name.ext"		     * we want directory = "full/file/"... do the maths */		    dir_length = strlen(fname) - strlen(current->filename)-1;		    DEBUG( DEBUG_FILES, "dir_length = %ld\n", (long) dir_length );		    current->directory = malloc( dir_length + 1 );		    strncpy( current->directory, fname+1, dir_length );		    *(current->directory+dir_length) = '\0'; /* nullterm */		    DEBUG( DEBUG_FILES, "directory = %s\n", current->directory );		    site_assignnames( current, the_site );		    current->localtime = item.st_mtime;		    current->localsize = item.st_size;		    current->diff = file_new;		    current->mode = item.st_mode;		    current->dir = false;		    the_site->totalnew += item.st_size;/*		    DEBUG( DEBUG_FILES, "new; size: %ld, time: %ld\n", item.st_size, item.st_mtime );  */		} else {		    /* Match found... compare it */		    current->localtime = item.st_mtime;		    current->localsize = item.st_size;		    the_site->numdeleted--;		    if( (current->localtime > current->remotetime) ||			(current->localsize != current->remotesize) ) {			/* Changed file */			current->diff = file_changed;			current->mode = item.st_mode;			the_site->numchanged++;			the_site->totalchanged += item.st_size;			DEBUG( DEBUG_FILES, "changed (%ld -> %ld)\n", current->localtime, current->remotetime );		    } else {			current->diff = file_unchanged;			current->updated = true;			the_site->numunchanged++;			DEBUG( DEBUG_FILES, "unchanged.\n" );		    }		    /* The names will already have been assigned */		}				    		/* Assign the ASCII type value */		current->isascii = file_isascii( fname, the_site );	    } else if( S_ISDIR( item.st_mode ) ) {		/* THIS IS A DIRECTORY! */		if( strcmp( ent->d_name, "." )==0 ||		    strcmp( ent->d_name, ".." )==0 ) {		    DEBUG( DEBUG_FILES, "ignored.\n" );		    continue;		}				DEBUG( DEBUG_FILES, "directory - " );		if( dirtop < MAXDIRS ) {		    temp = malloc( strlen( full ) + 2 );		    strcpy( temp, full );		    strcat( temp, "/" );		    dirstack[dirtop++] = temp;		} else {		    /* No more room in stack		     * FIXME: Report this to the user.*/		}		if( current == NULL ) {		    /* New Directory */		    the_site->numnew++;		    current = file_append( the_site );		    current->filename = strdup( base_name( fname ) );		    /* Work out the directory name */		    dir_length = strlen(fname) - strlen(current->filename )-1;		    current->directory = malloc( dir_length + 1 );		    strncpy( current->directory, fname+1, dir_length );		    *(current->directory+dir_length) = '\0'; /* null-term */		    site_assignnames( current, the_site );		    current->dir = true;		    current->diff = file_new;		    current->mode = item.st_mode;		    current->localsize = item.st_size;		    DEBUG( DEBUG_FILES, "new.\n" ); 		} else {		    /* It's an existing directory */		    the_site->numdeleted--;		    the_site->numunchanged++;		    current->diff = file_unchanged;		    current->updated = true;		    DEBUG( DEBUG_FILES, "existing.\n" ); 		}	    } #ifndef __EMX__	    else if( S_ISLNK( item.st_mode ) ) {		char tmp[BUFSIZ];		memset( tmp, 0, BUFSIZ );		DEBUG( DEBUG_FILES, "symlink being maintained.\n" );		if( readlink( full, tmp, BUFSIZ ) == -1 ) {		    DEBUG( DEBUG_FILES, "readlink failed: %s\n", 			   strerror(errno) );		    continue;		}		DEBUG( DEBUG_FILES, "Link target: %s\n", tmp );		if( current == NULL ) {		    /* New link */		    the_site->numnew++;		    current = file_append( the_site );		    current->filename = strdup( base_name( fname ) );		    dir_length = strlen(fname) - strlen(current->filename)-1;		    DEBUG( DEBUG_FILES, "dir_length = %ld\n", (long) dir_length );		    current->directory = malloc( dir_length + 1 );		    strncpy( current->directory, fname+1, dir_length );		    *(current->directory+dir_length) = '\0'; /* nullterm */		    DEBUG( DEBUG_FILES, "directory = %s\n", current->directory );		    current->locallink = strdup( tmp );		    current->diff = file_new;		    current->link = true;		    site_assignnames( current, the_site );		} else {		    /* Existing link... compare */		    the_site->numdeleted--;		    current->locallink = strdup( tmp );		    if( strcmp( current->remotelink, tmp ) == 0 ) {			/* Links match */			current->updated = true;			current->diff = file_unchanged;			the_site->numunchanged++;		    } else {			current->diff = file_changed;			the_site->numchanged++;		    }		}	    }#endif /* __EMX__ */	    else {		DEBUG( DEBUG_FILES, "something else.\n" );	    }	}	/* Close the open directory */	closedir( curdir );	/* And we're finished with this */	free( this );    }    return 0;}static void site_checkmoved( struct site_t *the_site ) {    /* Have any files been moved?     * We look for new files, then see if we can find a deleted file     * which matches filename, mod time, and size exactly.     *      * This is simplistic, and it is possible to get it wrong in some     * (unusual) circumstances:     *    Old: /bar/file1.zip, /foo/file1.zip      *    New: /new/file1.zip.     * If all the file1.zip's have the same size and mod time, it     * IS NOT POSSIBLE to know which one has become /new/file1.zip without      * storing remembering the contents of /bar/file1.zip somehow and      * comparing, or using a filesystem which remembers stuff. In any case     * it's pretty silly to try - so the whole shabang is optional.     *     * It would probably be better to search for DELETED files, then      * check them against NEW files, since files are more often added     * to sites then they are deleted. But hey, this is C, who'll notice?     */    struct site_file_t *search, *current;    /*  char *bname, *tmp; */    /* First off, find the new files... */    DEBUG( DEBUG_FILES, "Checking for moved files...\n" );

⌨️ 快捷键说明

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