示例#1
0
const char *DoWildCard( const char *base )
/***********************************************/
{
    PGROUP          pg;
    struct dirent   *entry;

    if( base != NULL ) {
        /* clean up from previous invocation */
        DoWildCardClose();

        if( strpbrk( base, WILD_METAS ) == NULL ) {
            return( base );
        }
        // create directory name and pattern
        path = MallocSafe( _MAX_PATH );
        pattern = MallocSafe( _MAX_PATH );
        strcpy( path, base );
        FixName( path );
        _splitpath2( path, pg.buffer, &pg.drive, &pg.dir, &pg.fname, &pg.ext );
        _makepath( path, pg.drive, pg.dir, ".", NULL );
        // create file name pattern
        _makepath( pattern, NULL, NULL, pg.fname, pg.ext );

        parent = opendir( path );
        if( parent == NULL ) {
            DoWildCardClose();
            return( base );
        }
    }

    if( parent == NULL ) {
        return( NULL );
    }

    assert( path != NULL && parent != NULL );

    while( (entry = readdir( parent )) != NULL ) {
#ifndef __UNIX__
        if( ( entry->d_attr & IGNORE_MASK ) == 0 ) {
#endif
            if( __fnmatch( pattern, entry->d_name ) ) {
                break;
            }
#ifndef __UNIX__
        }
#endif
    }
    if( entry == NULL ) {
        DoWildCardClose();
        return( base );
    }

    _splitpath2( path, pg.buffer, &pg.drive, &pg.dir, &pg.fname, &pg.ext );
    _makepath( path, pg.drive, pg.dir, entry->d_name, NULL );

    return( path );
}
示例#2
0
ap_fnmatch(const char *pattern, const char *string, int flags)
{
	int e;

	if (strnlen(pattern, PATH_MAX) == PATH_MAX ||
	    strnlen(string, PATH_MAX) == PATH_MAX)
		return (FNM_NOMATCH);
		
	e = __fnmatch(pattern, string, flags, __FNM_MAX_RECUR);
	if (e == -1)
		e = FNM_NOMATCH;
	return (e);
}
示例#3
0
static int __fnmatch( char *pattern, char *string )
/**************************************************
 * OS specific compare function FNameCmpChr
 * must be used for file names
 */
{
    char    *p;
    int     len;
    int     star_char;
    int     i;

    /*
     * check pattern section with wildcard characters
     */
    star_char = 0;
    while( IS_WILDCARD_CHAR( pattern ) ) {
        if( *pattern == '?' ) {
            if( *string == 0 ) {
                return( 0 );
            }
            string++;
        } else {
            star_char = 1;
        }
        pattern++;
    }
    if( *pattern == 0 ) {
        if( (*string == 0) || star_char ) {
            return( 1 );
        } else {
            return( 0 );
        }
    }
    /*
     * check pattern section with exact match
     * ( all characters except wildcards )
     */
    p = pattern;
    len = 0;
    do {
        if( star_char ) {
            if( string[len] == 0 ) {
                return( 0 );
            }
            len++;
        } else {
            if( FNameCmpChr( *pattern, *string ) != 0 ) {
                return( 0 );
            }
            string++;
        }
        pattern++;
    } while( *pattern && !IS_WILDCARD_CHAR( pattern ) );
    if( star_char == 0 ) {
        /*
         * match is OK, try next pattern section
         */
        return( __fnmatch( pattern, string ) );
    } else {
        /*
         * star pattern section, try locate exact match
         */
        while( *string ) {
            if( FNameCmpChr( *p, *string ) == 0 ) {
                for( i = 1; i < len; i++ ) {
                    if( FNameCmpChr( *(p + i), *(string + i) ) != 0 ) {
                        break;
                    }
                }
                if( i == len ) {
                    /*
                     * if rest doesn't match, find next occurence
                     */
                    if( __fnmatch( pattern, string + len ) ) {
                        return( 1 );
                    }
                }
            }
            string++;
        }
        return( 0 );
    }
}
示例#4
0
static int __fnmatch( char *pattern, char *string )
/*************************************************/
{
    char    *p;
    int     len;
    int     star_char;
    int     i;

    /*
     * check pattern section with wildcard characters
     */
    star_char = 0;
    while( ( *pattern == '*' ) || ( *pattern == '?' ) ) {
        if( *pattern == '?' ) {
            if( *string == 0 ) {
                return( 0 );
            }
            string++;
        } else {
            star_char = 1;
        }
        pattern++;
    }
    if( *pattern == 0 ) {
        if( ( *string == 0 ) || star_char ) {
            return( 1 );
        } else {
            return( 0 );
        }
    }
    /*
     * check pattern section with exact match
     * ( all characters except wildcards )
     */
    p = pattern;
    len = 0;
    do {
        if( star_char ) {
            if( string[ len ] == 0 ) {
                return( 0 );
            }
            len++;
        } else {
            if( *pattern != *string ) {
                return( 0 );
            }
            string++;
        }
        pattern++;
    } while( *pattern && ( *pattern != '*' ) && ( *pattern != '?' ) );
    if( star_char == 0 ) {
        /*
         * match is OK, try next pattern section
         */
        return( __fnmatch( pattern, string ) );
    } else {
        /*
         * star pattern section, try locate exact match
         */
        while( *string ) {
            if( *p == *string ) {
                for( i = 1; i < len; i++ ) {
                    if( *( p + i ) != *( string + i ) ) {
                        break;
                    }
                }
                if( i == len ) {
                    /*
                     * if rest doesn't match, find next occurence
                     */
                    if( __fnmatch( pattern, string + len ) ) {
                        return( 1 );
                    }
                }
            }
            string++;
        }
        return( 0 );
    }
}
示例#5
0
static copy_entry *BuildList( char *src, char *dst, bool test_abit )
{
    copy_entry          *head;
    copy_entry          *curr;
    copy_entry          **owner;
    char                *end;
    char                buff[_MAX_PATH2];
    char                full[_MAX_PATH];
    char                srcdir[_MAX_PATH];
    char                *drive;
    char                *dir;
    char                *fn;
    char                *ext;
    DIR                 *directory;
    struct dirent       *dent;
#ifndef __UNIX__
    FILE                *fp;
    unsigned            attr;
#else
    struct stat         statsrc, statdst;
    int                 dstrc, srcrc;
    char                pattern[_MAX_PATH];
#endif

    strcpy( srcdir, src );
    end = &dst[strlen( dst ) - 1];
    while( end[0] == ' ' || end[0] == '\t' ) {
        --end;
    }
    end[1] = '\0';
    if( strchr( srcdir, '*' ) == NULL && strchr( srcdir, '?' ) == NULL ) {
        /* no wild cards */
        head = Alloc( sizeof( *head ) );
        head->next = NULL;
        _fullpath( head->src, srcdir, sizeof( head->src ) );
        switch( *end ) {
        case '\\':
        case '/':
            /* need to append source file name */
            _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext );
            _makepath( full, NULL, dst, fn, ext );
            _fullpath( head->dst, full, sizeof( head->dst ) );
            break;
        default:
            _fullpath( head->dst, dst, sizeof( head->dst ) );
            break;
        }
        if( test_abit ) {
#ifndef __UNIX__
            fp = fopen( head->dst, "rb" );
            if( fp != NULL )
                fclose( fp );
            _dos_getfileattr( head->src, &attr );
            if( !( attr & _A_ARCH ) && fp != NULL ) {
                /* file hasn't changed */
                free( head );
                head = NULL;
            }
#else
            /* Linux has (strangely) no 'archive' attribute, compare modification times */
            dstrc = stat( head->dst, &statdst );
            srcrc = stat( head->src, &statsrc );
            if( (dstrc != -1) && (srcrc != -1) && (statdst.st_mtime == statsrc.st_mtime) ) {
                free( head );
                head = NULL;
            }
#endif
        }
        return( head );
    }
#ifdef __UNIX__
    _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext );
    _makepath( srcdir, drive, dir, NULL, NULL );
    _makepath( pattern, NULL, NULL, fn, ext );
#endif
    directory = opendir( srcdir );
    if( directory == NULL ) {
        Log( FALSE, "Can not open source directory '%s': %s\n", srcdir, strerror( errno ) );
        return( NULL );
    }
    head = NULL;
    owner = &head;
    for( ;; ) {
        dent = readdir( directory );
        if( dent == NULL )
            break;
#ifdef __UNIX__
        {
            struct stat buf;
            size_t len = strlen( srcdir );

            if( __fnmatch( pattern, dent->d_name ) == 0 )
                continue;

            strcat( srcdir, dent->d_name );
            stat( srcdir, &buf );
            srcdir[len] = '\0';
            if( S_ISDIR( buf.st_mode ) )
                continue;
        }
#else
        if( dent->d_attr & ( _A_SUBDIR | _A_VOLID ) )
            continue;
#endif
        curr = Alloc( sizeof( *curr ) );
        curr->next = NULL;
        _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext );
        _makepath( full, drive, dir, dent->d_name, NULL );
        _fullpath( curr->src, full, sizeof( curr->src ) );
        strcpy( full, dst );
        switch( *end ) {
        case '\\':
        case '/':
            strcat( full, dent->d_name );
            break;
        }
        _fullpath( curr->dst, full, sizeof( curr->dst ) );
        if( test_abit ) {
#ifndef __UNIX__
            fp = fopen( curr->dst, "rb" );
            if( fp != NULL )
                fclose( fp );
            if( !(dent->d_attr & _A_ARCH) && fp != NULL ) {
                /* file hasn't changed */
                free( curr );
                continue;
            }
#else
            /* Linux has (strangely) no 'archive' attribute, compare modification times */
            dstrc = stat( curr->dst, &statdst );
            srcrc = stat( curr->src, &statsrc );
            if( (dstrc != -1) && (srcrc != -1) && (statdst.st_mtime == statsrc.st_mtime) ) {
                free( curr );
                continue;
            }
#endif
        }
        *owner = curr;
        owner = &curr->next;
    }
    return( head );
}
示例#6
0
int
__fnmatch(const char *pattern, const char *string, int flags, int recur)
{
	const char *stringstart;
	char c, test;
	int e;

	if (recur-- == 0)
		return (-1);

	for (stringstart = string;;) {
		switch (c = *pattern++) {
		case EOS:
			return (*string == EOS ? 0 : FNM_NOMATCH);
		case '?':
			if (*string == EOS)
				return (FNM_NOMATCH);
			if (*string == '/' && (flags & FNM_PATHNAME))
				return (FNM_NOMATCH);
			if (*string == '.' && (flags & FNM_PERIOD) &&
			    (string == stringstart ||
			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
				return (FNM_NOMATCH);
			++string;
			break;
		case '*':
			c = *pattern;
			/* Collapse multiple stars. */
			while (c == '*')
				c = *++pattern;

			if (*string == '.' && (flags & FNM_PERIOD) &&
			    (string == stringstart ||
			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
				return (FNM_NOMATCH);

			/* Optimize for pattern with * at end or before /. */
			if (c == EOS) {
				if (flags & FNM_PATHNAME)
					return (strchr(string, '/') == NULL ? 0 : FNM_NOMATCH);
				else
					return (0);
			}
			else if (c == '/' && flags & FNM_PATHNAME) {
				if ((string = strchr(string, '/')) == NULL)
					return (FNM_NOMATCH);
				break;
			}

			/* General case, use recursion. */
			while ((test = *string) != EOS) {
				e = __fnmatch(pattern, string,
				    flags & ~FNM_PERIOD, recur);
				if (e != FNM_NOMATCH)
					return (e);
				if (test == '/' && flags & FNM_PATHNAME)
					break;
				++string;
			}
			return (FNM_NOMATCH);
		case '[':
			if (*string == EOS)
				return (FNM_NOMATCH);
			if (*string == '/' && flags & FNM_PATHNAME)
				return (FNM_NOMATCH);
			if (*string == '.' && (flags & FNM_PERIOD) &&
			    (string == stringstart ||
			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
				return (FNM_NOMATCH);
			if ((pattern = rangematch(pattern, *string, flags))
			    == NULL)
				return (FNM_NOMATCH);
			++string;
			break;
		case '\\':
			if (!(flags & FNM_NOESCAPE))
				if ((c = *pattern++) == EOS) {
					c = '\\';
					--pattern;
				}
			/* FALLTHROUGH */
		default:
			if (flags & FNM_CASE_BLIND) {
				if (ap_tolower(c) != ap_tolower(*string))
					return (FNM_NOMATCH);
			}
			else if (c != *string)
				return (FNM_NOMATCH);
			string++;
			break;
		}
	/* NOTREACHED */
	}
}