/*
 * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <descrip.h>
#include <namdef.h>
#include <rmsdef.h>
#include <libfildef.h>
#include <lib$routines.h>
#include <strdef.h>
#include <str$routines.h>
#include <stsdef.h>
#ifndef LPDIR_H
# include "LPdir.h"
#endif
#include "vms_rms.h"

/* Some compiler options hide EVMSERR. */
#ifndef EVMSERR
# define EVMSERR        65535   /* error for non-translatable VMS errors */
#endif

struct LP_dir_context_st {
    unsigned long VMS_context;
    char filespec[NAMX_MAXRSS + 1];
    char result[NAMX_MAXRSS + 1];
    struct dsc$descriptor_d filespec_dsc;
    struct dsc$descriptor_d result_dsc;
};

const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
{
    int status;
    char *p, *r;
    size_t l;
    unsigned long flags = 0;

/* Arrange 32-bit pointer to (copied) string storage, if needed. */
#if __INITIAL_POINTER_SIZE == 64
# pragma pointer_size save
# pragma pointer_size 32
    char *ctx_filespec_32p;
# pragma pointer_size restore
    char ctx_filespec_32[NAMX_MAXRSS + 1];
#endif                          /* __INITIAL_POINTER_SIZE == 64 */

#ifdef NAML$C_MAXRSS
    flags |= LIB$M_FIL_LONG_NAMES;
#endif

    if (ctx == NULL || directory == NULL) {
        errno = EINVAL;
        return 0;
    }

    errno = 0;
    if (*ctx == NULL) {
        size_t filespeclen = strlen(directory);
        char *filespec = NULL;

        if (filespeclen == 0) {
            errno = ENOENT;
            return 0;
        }

        /* MUST be a VMS directory specification!  Let's estimate if it is. */
        if (directory[filespeclen - 1] != ']'
            && directory[filespeclen - 1] != '>'
            && directory[filespeclen - 1] != ':') {
            errno = EINVAL;
            return 0;
        }

        filespeclen += 4;       /* "*.*;" */

        if (filespeclen > NAMX_MAXRSS) {
            errno = ENAMETOOLONG;
            return 0;
        }

        *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
        if (*ctx == NULL) {
            errno = ENOMEM;
            return 0;
        }
        memset(*ctx, '\0', sizeof(LP_DIR_CTX));

        strcpy((*ctx)->filespec, directory);
        strcat((*ctx)->filespec, "*.*;");

/* Arrange 32-bit pointer to (copied) string storage, if needed. */
#if __INITIAL_POINTER_SIZE == 64
# define CTX_FILESPEC ctx_filespec_32p
        /* Copy the file name to storage with a 32-bit pointer. */
        ctx_filespec_32p = ctx_filespec_32;
        strcpy(ctx_filespec_32p, (*ctx)->filespec);
#else                           /* __INITIAL_POINTER_SIZE == 64 */
# define CTX_FILESPEC (*ctx)->filespec
#endif                          /* __INITIAL_POINTER_SIZE == 64 [else] */

        (*ctx)->filespec_dsc.dsc$w_length = filespeclen;
        (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
        (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
        (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
    }

    (*ctx)->result_dsc.dsc$w_length = 0;
    (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
    (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
    (*ctx)->result_dsc.dsc$a_pointer = 0;

    status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
                           &(*ctx)->VMS_context, 0, 0, 0, &flags);

    if (status == RMS$_NMF) {
        errno = 0;
        vaxc$errno = status;
        return NULL;
    }

    if (!$VMS_STATUS_SUCCESS(status)) {
        errno = EVMSERR;
        vaxc$errno = status;
        return NULL;
    }

    /*
     * Quick, cheap and dirty way to discard any device and directory, since
     * we only want file names
     */
    l = (*ctx)->result_dsc.dsc$w_length;
    p = (*ctx)->result_dsc.dsc$a_pointer;
    r = p;
    for (; *p; p++) {
        if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */
            p++;
        } else if (*p == ':' || *p == '>' || *p == ']') {
            l -= p + 1 - r;
            r = p + 1;
        } else if (*p == ';') {
            l = p - r;
            break;
        }
    }

    strncpy((*ctx)->result, r, l);
    (*ctx)->result[l] = '\0';
    str$free1_dx(&(*ctx)->result_dsc);

    return (*ctx)->result;
}

int LP_find_file_end(LP_DIR_CTX **ctx)
{
    if (ctx != NULL && *ctx != NULL) {
        int status = lib$find_file_end(&(*ctx)->VMS_context);

        free(*ctx);

        if (!$VMS_STATUS_SUCCESS(status)) {
            errno = EVMSERR;
            vaxc$errno = status;
            return 0;
        }
        return 1;
    }
    errno = EINVAL;
    return 0;
}
