/*
 * 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.
 *  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 "pathsys.h"

# ifdef OS_VMS

/*
 * filevms.c - scan directories and libaries on VMS
 *
 * 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().
 *
 * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length!
 * 05/03/96 (seiwald) - split into pathvms.c
 */

# include <rms.h>
# include <iodef.h>
# include <ssdef.h>
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <descrip.h>

#include <lbrdef.h>
#include <credef.h>
#include <mhddef.h>
#include <lhidef.h>
#include <lib$routines.h>
#include <starlet.h>

/* Supply missing prototypes for lbr$-routines*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

int lbr$set_module(
    void **,
    unsigned long *,
    struct dsc$descriptor_s *,
    unsigned short *,
    void * );

int lbr$open( void **,
    struct dsc$descriptor_s *,
    void *,
    void *,
    void *,
    void *,
    void * );

int lbr$ini_control(
    void **,
    unsigned long *,
    unsigned long *,
    void * );

int lbr$get_index(
    void **,
    unsigned long *,
    int (*func)( struct dsc$descriptor_s *, unsigned long *),
    void * );

int lbr$close(
    void ** );

#ifdef __cplusplus
}
#endif /* __cplusplus */

static void
file_cvttime(
    unsigned int *curtime,
    time_t *unixtime )
{
    static const size_t divisor = 10000000;
    static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */
    int delta[2], remainder;

    lib$subx( curtime, bastim, delta );
    lib$ediv( &divisor, delta, unixtime, &remainder );
}

# define DEFAULT_FILE_SPECIFICATION "[]*.*;0"

# define min( a,b ) ((a)<(b)?(a):(b))

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

    struct FAB xfab;
    struct NAM xnam;
    struct XABDAT xab;
    char esa[256];
    char filename[256];
    string filename2[1];
    char dirname[256];
    register int status;
    PATHNAME f;

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

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

    /* get the input file specification
     */
    xnam = cc$rms_nam;
    xnam.nam$l_esa = esa;
    xnam.nam$b_ess = sizeof( esa ) - 1;
    xnam.nam$l_rsa = filename;
    xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS );

    xab = cc$rms_xabdat;                /* initialize extended attributes */
    xab.xab$b_cod = XAB$C_DAT;      /* ask for date */
    xab.xab$l_nxt = NULL;               /* terminate XAB chain      */

    xfab = cc$rms_fab;
    xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION;
    xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1;
    xfab.fab$l_fop = FAB$M_NAM;
    xfab.fab$l_fna = dir;           /* address of file name     */
    xfab.fab$b_fns = strlen( dir );     /* length of file name      */
    xfab.fab$l_nam = &xnam;         /* address of NAB block     */
    xfab.fab$l_xab = (char *)&xab;       /* address of XAB block     */


    status = sys$parse( &xfab );

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

    if ( !( status & 1 ) )
    return;



    /* Add bogus directory for [000000] */

    if ( !strcmp( dir, "[000000]" ) )
    {
    (*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
    }

    /* Add bogus directory for [] */

    if ( !strcmp( dir, "[]" ) )
    {
        (*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ );
        (*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ );
    }

    string_new( filename2 );
    while ( (status = sys$search( &xfab )) & 1 )
    {
    char *s;
    time_t time;

    /* "I think that might work" - eml */

    sys$open( &xfab );
    sys$close( &xfab );

    file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );

    filename[xnam.nam$b_rsl] = '\0';

    /* What we do with the name depends on the suffix: */
    /* .dir is a directory */
    /* .xxx is a file with a suffix */
    /* . is no suffix at all */

    if ( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) )
    {
        /* directory */
        sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name );
        f.f_dir.ptr = dirname;
        f.f_dir.len = strlen( dirname );
        f.f_base.ptr = 0;
        f.f_base.len = 0;
        f.f_suffix.ptr = 0;
        f.f_suffix.len = 0;
    }
    else
    {
        /* normal file with a suffix */
        f.f_dir.ptr = 0;
        f.f_dir.len = 0;
        f.f_base.ptr = xnam.nam$l_name;
        f.f_base.len = xnam.nam$b_name;
        f.f_suffix.ptr = xnam.nam$l_type;
        f.f_suffix.len = xnam.nam$b_type;
    }

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

    /*
    if ( DEBUG_SEARCH )
        printf("root '%s' base %.*s suf %.*s = %s\n",
            dir,
            xnam.nam$b_name, xnam.nam$l_name,
            xnam.nam$b_type, xnam.nam$l_type,
            filename2 );
    */

    (*func)( closure, filename2->value, 1 /* time valid */, time );
    }
    string_free( filename2 );
}

int
file_time(
    char    *filename,
    time_t  *time )
{
    /* This should never be called, as all files are */
    /* timestampped in file_dirscan() and file_archscan() */
    return -1;
}

static char *VMS_archive = 0;
static scanback VMS_func;
static void *VMS_closure;
static void *context;

static int
file_archmember(
    struct dsc$descriptor_s *module,
    unsigned long *rfa )
{
    static struct dsc$descriptor_s bufdsc =
          {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};

    struct mhddef *mhd;
    char filename[128];
    char buf[ MAXJPATH ];

    int status;
    time_t library_date;

    register int i;
    register char *p;

    bufdsc.dsc$a_pointer = filename;
    bufdsc.dsc$w_length = sizeof( filename );
    status = lbr$set_module( &context, rfa, &bufdsc,
                 &bufdsc.dsc$w_length, NULL );

    if ( !(status & 1) )
    return ( 1 );

    mhd = (struct mhddef *)filename;

    file_cvttime( &mhd->mhd$l_datim, &library_date );

    for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p )
    filename[ i ] = *p;

    filename[ i ] = '\0';

    sprintf( buf, "%s(%s.obj)", VMS_archive, filename );

    (*VMS_func)( VMS_closure, buf, 1 /* time valid */, (time_t)library_date );

    return ( 1 );
}


void file_archscan( char * archive, scanback func, void * closure )
{
    static struct dsc$descriptor_s library =
          {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};

    unsigned long lfunc = LBR$C_READ;
    unsigned long typ = LBR$C_TYP_UNK;
    unsigned long index = 1;

    register int status;

    VMS_archive = archive;
    VMS_func = func;
    VMS_closure = closure;

    status = lbr$ini_control( &context, &lfunc, &typ, NULL );
    if ( !( status & 1 ) )
        return;

    library.dsc$a_pointer = archive;
    library.dsc$w_length = strlen( archive );

    status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL );
    if ( !( status & 1 ) )
        return;

    (void) lbr$get_index( &context, &index, file_archmember, NULL );

    (void) lbr$close( &context );
}

# endif /* VMS */
