diff options
Diffstat (limited to 'thirdparty/openssl/crypto/LPdir_vms.c')
| -rw-r--r-- | thirdparty/openssl/crypto/LPdir_vms.c | 195 | 
1 files changed, 195 insertions, 0 deletions
diff --git a/thirdparty/openssl/crypto/LPdir_vms.c b/thirdparty/openssl/crypto/LPdir_vms.c new file mode 100644 index 0000000000..88c7ddd85c --- /dev/null +++ b/thirdparty/openssl/crypto/LPdir_vms.c @@ -0,0 +1,195 @@ +/* + * 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; +}  |