Beispiel #1
0
file_info_t * filelist_back(  FILELIST * list )
{
    if ( filelist_empty( list )
         || list->tail == 0 ) return (file_info_t *)0;

    return list->tail->value;
}
Beispiel #2
0
int file_collect_archive_content_( file_archive_info_t * const archive )
{
    int fd;
    char fl_magic[ SAIAMAG ];
    const char * path = object_str( archive->file->name );

    if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members );

    if ( ( fd = open( path, O_RDONLY, 0 ) ) < 0 )
        return -1;

    if ( read( fd, fl_magic, SAIAMAG ) != SAIAMAG ||
            lseek( fd, 0, SEEK_SET ) == -1 )
    {
        close( fd );
        return -1;
    }

    if ( !strncmp( AIAMAG, fl_magic, SAIAMAG ) )
    {
        /* read small variant */
        collect_archive_content_small( fd, archive );
    }
#ifdef AR_HSZ_BIG
    else if ( !strncmp( AIAMAGBIG, fl_magic, SAIAMAG ) )
    {
        /* read big variant */
        collect_archive_content_big( fd, archive );
    }
#endif

    close( fd );

    return 0;
}
Beispiel #3
0
FILELISTITER filelist_begin( FILELIST * list )
{
    if ( filelist_empty( list )
         || list->head == 0 ) return (FILELISTITER)0;

    return &list->head->value;
}
Beispiel #4
0
file_info_t * filelist_front(  FILELIST * list )
{
    if ( filelist_empty( list )
         || list->head == 0 ) return (file_info_t *)0;

    return list->head->value;
}
Beispiel #5
0
int filelist_length( FILELIST * list )
{
    int result = 0;
    if ( !filelist_empty( list ) ) result = list->size;

    return result;
}
Beispiel #6
0
void filelist_free( FILELIST * list )
{
    FILELISTITER iter;

    if ( filelist_empty( list ) ) return;

    while ( filelist_length( list ) ) filelist_pop_front( list );

#ifdef BJAM_NO_MEM_CACHE
    BJAM_FREE( list );
#endif
}
Beispiel #7
0
static void file_archivescan_impl( OBJECT * path, archive_scanback func, void * closure )
{
    file_archive_info_t * const archive = file_archive_query( path );
    if ( !archive || !archive->file->is_file )
        return;

    /* Lazy collect the archive content information. */
    if ( filelist_empty( archive->members ) )
    {
        if ( DEBUG_BINDSCAN )
            printf( "scan archive %s\n", object_str( archive->file->name ) );
        if ( file_collect_archive_content_( archive ) < 0 )
            return;
    }

    /* OS specific part of the file_archivescan operation. */
    file_archivescan_( archive, func, closure );

    /* Report the collected archive content. */
    {
        FILELISTITER iter = filelist_begin( archive->members );
        FILELISTITER const end = filelist_end( archive->members );
        char buf[ MAXJPATH ];

        for ( ; iter != end ; iter = filelist_next( iter ) )
        {
            file_info_t * member_file = filelist_item( iter );
            LIST * symbols = member_file->files;

            /* Construct member path: 'archive-path(member-name)'
             */
            sprintf( buf, "%s(%s)",
                object_str( archive->file->name ),
                object_str( member_file->name ) );

            {
                OBJECT * const member = object_new( buf );
                (*func)( closure, member, symbols, 1, &member_file->time );
                object_free( member );
            }
        }
    }
}
Beispiel #8
0
FILELIST * filelist_pop_front( FILELIST * list )
{
    FILEITEM * item;

    if ( filelist_empty( list ) ) return list;

    item = list->head;

    if ( item )
    {
        if ( item->value ) free_file_info( item->value, 0 );

        list->head = item->next;
        list->size--;
        if ( !list->size ) list->tail = list->head;

#ifdef BJAM_NO_MEM_CACHE
        BJAM_FREE( item );
#endif
    }

    return list;
}
Beispiel #9
0
/*
 * file_archscan() - scan an archive for files
 */
void file_archscan( char const * arch, scanback func, void * closure )
{
    OBJECT * path = object_new( arch );
    file_archive_info_t * archive = file_archive_query( path );

    object_free( path );

    if ( filelist_empty( archive->members ) )
    {
        if ( file_collect_archive_content_( archive ) < 0 )
            return;
    }

    /* Report the collected archive content. */
    {
        FILELISTITER iter = filelist_begin( archive->members );
        FILELISTITER const end = filelist_end( archive->members );
        char buf[ MAXJPATH ];

        for ( ; iter != end ; iter = filelist_next( iter ) )
        {
            file_info_t * member_file = filelist_item( iter );
            LIST * symbols = member_file->files;

            /* Construct member path: 'archive-path(member-name)'
             */
            sprintf( buf, "%s(%s)",
                     object_str( archive->file->name ),
                     object_str( member_file->name ) );
            {
                OBJECT * const member = object_new( buf );
                (*func)( closure, member, 1 /* time valid */, &member_file->time );
                object_free( member );
            }
        }
    }
}
Beispiel #10
0
FILELIST * filelist_push_front( FILELIST * list, OBJECT * path )
{
    FILEITEM * item;
    file_info_t * file;

    /* Lazy initialization
     */
    if ( filelist_empty( list ) )
    {
        list = filelist_new( path );
        return list;
    }


    item = (FILEITEM *)BJAM_MALLOC( sizeof( FILEITEM ) );
    memset( item, 0, sizeof( *item ) );
    item->value = (file_info_t *)BJAM_MALLOC( sizeof( file_info_t ) );

    file = item->value;
    memset( file, 0, sizeof( *file ) );

    file->name = path;
    file->files = L0;

    if ( list->head )
    {
        item->next = list->head;
    }
    else
    {
        list->tail = item;
    }
    list->head = item;
    list->size++;

    return list;
}
Beispiel #11
0
int file_collect_archive_content_( file_archive_info_t * const archive )
{
#ifndef NO_AR
    struct ar_hdr ar_hdr;
    char * string_table = 0;
    char buf[ MAXJPATH ];
    long offset;
    int fd;
    const char * path = object_str( archive->file->name );

    if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members );

    if ( ( fd = open( path, O_RDONLY, 0 ) ) < 0 )
        return -1;

    if ( read( fd, buf, SARMAG ) != SARMAG ||
            strncmp( ARMAG, buf, SARMAG ) )
    {
        close( fd );
        return -1;
    }

    offset = SARMAG;

    if ( DEBUG_BINDSCAN )
        out_printf( "scan archive %s\n", path );

    while ( ( read( fd, &ar_hdr, SARHDR ) == SARHDR ) &&
            !( memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG )
#ifdef ARFZMAG
               /* OSF also has a compressed format */
               && memcmp( ar_hdr.ar_fmag, ARFZMAG, SARFMAG )
#endif
             ) )
    {
        char   lar_name_[ 257 ];
        char * lar_name = lar_name_ + 1;
        long   lar_date;
        long   lar_size;
        long   lar_offset;
        char * c;
        char * src;
        char * dest;

        strncpy( lar_name, ar_hdr.ar_name, sizeof( ar_hdr.ar_name ) );

        sscanf( ar_hdr.ar_date, "%ld", &lar_date );
        sscanf( ar_hdr.ar_size, "%ld", &lar_size );

        if ( ar_hdr.ar_name[ 0 ] == '/' )
        {
            if ( ar_hdr.ar_name[ 1 ] == '/' )
            {
                /* This is the "string table" entry of the symbol table, holding
                 * filename strings longer than 15 characters, i.e. those that
                 * do not fit into ar_name.
                 */
                string_table = (char *)BJAM_MALLOC_ATOMIC( lar_size );
                lseek( fd, offset + SARHDR, 0 );
                if ( read( fd, string_table, lar_size ) != lar_size )
                    out_printf("error reading string table\n");
            }
            else if ( string_table && ar_hdr.ar_name[ 1 ] != ' ' )
            {
                /* Long filenames are recognized by "/nnnn" where nnnn is the
                 * offset of the string in the string table represented in ASCII
                 * decimals.
                 */
                dest = lar_name;
                lar_offset = atoi( lar_name + 1 );
                src = &string_table[ lar_offset ];
                while ( *src != '/' )
                    *dest++ = *src++;
                *dest = '/';
            }
        }

        c = lar_name - 1;
        while ( ( *++c != ' ' ) && ( *c != '/' ) );
        *c = '\0';

        if ( DEBUG_BINDSCAN )
            out_printf( "archive name %s found\n", lar_name );

        sprintf( buf, "%s", lar_name );

        if ( strcmp( buf, "") != 0 )
        {
            file_info_t * member = 0;

            archive->members = filelist_push_back( archive->members, object_new( buf ) );
            member = filelist_back( archive->members );
            member->is_file = 1;
            member->is_dir = 0;
            member->exists = 0;
            timestamp_init( &member->time, (time_t)lar_date, 0 );
        }

        offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
        lseek( fd, offset, 0 );
    }

    if ( string_table )
        BJAM_FREE( string_table );

    close( fd );
#endif  /* NO_AR */

    return 0;
}