/*
 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

/*  This file is ALSO:
 *  Copyright 2001-2004 David Abrahams.
 *  Copyright 2005 Rene Rivera.
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 */

# include "jam.h"
# include "filesys.h"
# include "strings.h"
# include "pathsys.h"
# include "newstr.h"
# include <stdio.h>

#if defined(sun) || defined(__sun) || defined(linux)
# include <unistd.h> /* needed for read and close prototype */
#endif

# ifdef USE_FILEUNIX

#if defined(sun) || defined(__sun)
# include <unistd.h> /* needed for read and close prototype */
#endif

# if defined( OS_SEQUENT ) || \
     defined( OS_DGUX ) || \
     defined( OS_SCO ) || \
     defined( OS_ISC )
# define PORTAR 1
# endif

# ifdef __EMX__
# include <sys/types.h>
# include <sys/stat.h>
# endif

# if defined( OS_RHAPSODY ) || \
     defined( OS_MACOSX ) || \
     defined( OS_NEXT )
/* need unistd for rhapsody's proper lseek */
# include <sys/dir.h>
# include <unistd.h>
# define STRUCT_DIRENT struct direct
# else
# include <dirent.h>
# define STRUCT_DIRENT struct dirent
# endif

# ifdef OS_COHERENT
# include <arcoff.h>
# define HAVE_AR
# endif

# if defined( OS_MVS ) || \
         defined( OS_INTERIX )

#define ARMAG   "!<arch>\n"
#define SARMAG  8
#define ARFMAG  "`\n"

struct ar_hdr       /* archive file member header - printable ascii */
{
    char    ar_name[16];    /* file member name - `/' terminated */
    char    ar_date[12];    /* file member date - decimal */
    char    ar_uid[6];  /* file member user id - decimal */
    char    ar_gid[6];  /* file member group id - decimal */
    char    ar_mode[8]; /* file member mode - octal */
    char    ar_size[10];    /* file member size - decimal */
    char    ar_fmag[2]; /* ARFMAG - string to end header */
};

# define HAVE_AR
# endif

# if defined( OS_QNX ) || \
     defined( OS_BEOS ) || \
     defined( OS_MPEIX )
# define NO_AR
# define HAVE_AR
# endif

# ifndef HAVE_AR

# ifdef OS_AIX
/* Define those for AIX to get the definitions for both the small and the
 * big variant of the archive file format. */
#    define __AR_SMALL__
#    define __AR_BIG__
# endif

# include <ar.h>
# endif

/*
 * fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS
 *
 * External routines:
 *
 *  file_dirscan() - scan a directory for files
 *  file_time() - get timestamp of file, if not done by file_dirscan()
 *  file_archscan() - scan an archive for files
 *
 * File_dirscan() and file_archscan() call back a caller provided function
 * for each file found.  A flag to this callback function lets file_dirscan()
 * and file_archscan() indicate that a timestamp is being provided with the
 * file.   If file_dirscan() or file_archscan() do not provide the file's
 * timestamp, interested parties may later call file_time().
 *
 * 04/08/94 (seiwald) - Coherent/386 support added.
 * 12/19/94 (mikem) - solaris string table insanity support
 * 02/14/95 (seiwald) - parse and build /xxx properly
 * 05/03/96 (seiwald) - split into pathunix.c
 * 11/21/96 (peterk) - BEOS does not have Unix-style archives
 */


/*
 * file_dirscan() - scan a directory for files.
 */

void file_dirscan( char * dir, scanback func, void * closure )
{
    PROFILE_ENTER( FILE_DIRSCAN );

    file_info_t * d = 0;

    d = file_query( dir );

    if ( !d || !d->is_dir )
    {
        PROFILE_EXIT( FILE_DIRSCAN );
        return;
    }

    if ( ! d->files )
    {
        LIST* files = L0;
        PATHNAME f;
        DIR *dd;
        STRUCT_DIRENT *dirent;
        string filename[1];

        /* First enter directory itself */

        memset( (char *)&f, '\0', sizeof( f ) );

        f.f_dir.ptr = dir;
        f.f_dir.len = strlen(dir);

        dir = *dir ? dir : ".";

        /* Now enter contents of directory. */

        if ( !( dd = opendir( dir ) ) )
        {
            PROFILE_EXIT( FILE_DIRSCAN );
            return;
        }

        if ( DEBUG_BINDSCAN )
            printf( "scan directory %s\n", dir );

        string_new( filename );
        while ( ( dirent = readdir( dd ) ) )
        {
            # ifdef old_sinix
            /* Broken structure definition on sinix. */
            f.f_base.ptr = dirent->d_name - 2;
            # else
            f.f_base.ptr = dirent->d_name;
            # endif
            f.f_base.len = strlen( f.f_base.ptr );

            string_truncate( filename, 0 );
            path_build( &f, filename, 0 );

            files = list_new( files, newstr(filename->value) );
            file_query( filename->value );
        }
        string_free( filename );

        closedir( dd );

        d->files = files;
    }

    /* Special case / : enter it */
    {
        unsigned long len = strlen(d->name);
        if ( ( len == 1 ) && ( d->name[0] == '/' ) )
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
    }

    /* Now enter contents of directory */
    if ( d->files )
    {
        LIST * files = d->files;
        while ( files )
        {
            file_info_t * ff = file_info( files->string );
            (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
            files = list_next( files );
        }
    }

    PROFILE_EXIT( FILE_DIRSCAN );
}


file_info_t * file_query( char * filename )
{
    file_info_t * ff = file_info( filename );
    if ( ! ff->time )
    {
        struct stat statbuf;

        if ( stat( *filename ? filename : ".", &statbuf ) < 0 )
            return 0;

        ff->is_file = statbuf.st_mode & S_IFREG ? 1 : 0;
        ff->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0;
        ff->size = statbuf.st_size;
        ff->time = statbuf.st_mtime ? statbuf.st_mtime : 1;
    }
    return ff;
}

/*
 * file_time() - get timestamp of file, if not done by file_dirscan()
 */

int
file_time(
    char    *filename,
    time_t  *time )
{
    file_info_t * ff = file_query( filename );
    if ( !ff ) return -1;
    *time = ff->time;
    return 0;
}

int file_is_file(char* filename)
{
    file_info_t * ff = file_query( filename );
    if ( !ff ) return -1;
    return ff->is_file;
}


/*
 * file_archscan() - scan an archive for files
 */

# ifndef AIAMAG /* God-fearing UNIX */

# define SARFMAG 2
# define SARHDR sizeof( struct ar_hdr )

void
file_archscan(
    char *archive,
    scanback func,
    void *closure )
{
# ifndef NO_AR
    struct ar_hdr ar_hdr;
    char buf[ MAXJPATH ];
    long offset;
    char    *string_table = 0;
    int fd;

    if ( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
        return;

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

    offset = SARMAG;

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

    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,
            ** which holds strings of filenames that are longer than
            ** 15 characters (ie. don't fit into a ar_name
            */

            string_table = (char *)BJAM_MALLOC_ATOMIC(lar_size);
            lseek(fd, offset + SARHDR, 0);
            if (read(fd, string_table, lar_size) != lar_size)
            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 )
        printf( "archive name %s found\n", lar_name );

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

        (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );

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

    if (string_table)
        BJAM_FREE(string_table);

    close( fd );

# endif /* NO_AR */

}

# else /* AIAMAG - RS6000 AIX */

static void file_archscan_small(
    int fd, char const *archive, scanback func, void *closure)
{
    struct fl_hdr fl_hdr;

    struct {
        struct ar_hdr hdr;
        char pad[ 256 ];
    } ar_hdr ;

    char buf[ MAXJPATH ];
    long offset;

    if ( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ)
        return;

    sscanf( fl_hdr.fl_fstmoff, "%ld", &offset );

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

    while ( ( offset > 0 )
           && ( lseek( fd, offset, 0 ) >= 0 )
           && ( read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) ) )
    {
        long lar_date;
        int  lar_namlen;

        sscanf( ar_hdr.hdr.ar_namlen, "%d" , &lar_namlen );
        sscanf( ar_hdr.hdr.ar_date  , "%ld", &lar_date   );
        sscanf( ar_hdr.hdr.ar_nxtmem, "%ld", &offset     );

        if ( !lar_namlen )
            continue;

        ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';

        sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name );

        (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
    }
}

/* Check for OS version which supports the big variant. */
#ifdef AR_HSZ_BIG

static void file_archscan_big(
    int fd, char const *archive, scanback func, void *closure)
{
    struct fl_hdr_big fl_hdr;

    struct {
        struct ar_hdr_big hdr;
        char pad[ 256 ];
    } ar_hdr ;

    char buf[ MAXJPATH ];
    long long offset;

    if ( read( fd, (char *)&fl_hdr, FL_HSZ_BIG) != FL_HSZ_BIG)
        return;

    sscanf( fl_hdr.fl_fstmoff, "%lld", &offset );

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

    while ( ( offset > 0 )
           && ( lseek( fd, offset, 0 ) >= 0 )
           && ( read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) ) )
    {
        long lar_date;
        int  lar_namlen;

        sscanf( ar_hdr.hdr.ar_namlen, "%d"  , &lar_namlen );
        sscanf( ar_hdr.hdr.ar_date  , "%ld" , &lar_date   );
        sscanf( ar_hdr.hdr.ar_nxtmem, "%lld", &offset     );

        if ( !lar_namlen )
            continue;

        ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';

        sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name );

        (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
    }

}

#endif /* AR_HSZ_BIG */

void file_archscan(char *archive, scanback func, void *closure)
{
    int fd;
    char fl_magic[SAIAMAG];

    if (( fd = open(archive, O_RDONLY, 0)) < 0)
        return;

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

    if (strncmp(AIAMAG, fl_magic, SAIAMAG) == 0)
    {
        /* read small variant */
        file_archscan_small(fd, archive, func, closure);
    }
#ifdef AR_HSZ_BIG
    else if (strncmp(AIAMAGBIG, fl_magic, SAIAMAG) == 0)
    {
        /* read big variant */
        file_archscan_big(fd, archive, func, closure);
    }
#endif

    close( fd );
}

# endif /* AIAMAG - RS6000 AIX */

# endif /* USE_FILEUNIX */
