X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdso%2Fdso_vms.c;h=868513c3915d0d4108b9cbd427824c557018e971;hp=d2c06ddafae51bb3386444e66463830506b73bcb;hb=da12bfca5196819db2d2b1880cd6231f8320e330;hpb=3aa477f6ec8f184ea72eca19826c92abc488ad12 diff --git a/crypto/dso/dso_vms.c b/crypto/dso/dso_vms.c index d2c06ddafa..868513c391 100644 --- a/crypto/dso/dso_vms.c +++ b/crypto/dso/dso_vms.c @@ -1,4 +1,4 @@ -/* dso_vms.c */ +/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */ /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL * project 2000. */ @@ -59,26 +59,38 @@ #include #include #include -#ifdef VMS -#pragma message disable DOLLARID -#include -#include -#include -#include -#include -#endif #include "cryptlib.h" #include -#ifndef VMS +#ifndef OPENSSL_SYS_VMS DSO_METHOD *DSO_METHOD_vms(void) { return NULL; } #else + +#pragma message disable DOLLARID +#include +#include +#include +#include +#include +#include "vms_rms.h" + +/* Some compiler options may mask the declaration of "_malloc32". */ +#if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 + void * _malloc32 (__size_t); +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ +#endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */ + + #pragma message disable DOLLARID -static int vms_load(DSO *dso, const char *filename); +static int vms_load(DSO *dso); static int vms_unload(DSO *dso); static void *vms_bind_var(DSO *dso, const char *symname); static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); @@ -87,8 +99,11 @@ static int vms_unbind_var(DSO *dso, char *symname, void *symptr); static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); static int vms_init(DSO *dso); static int vms_finish(DSO *dso); -#endif static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); +#endif +static char *vms_name_converter(DSO *dso, const char *filename); +static char *vms_merger(DSO *dso, const char *filespec1, + const char *filespec2); static DSO_METHOD dso_meth_vms = { "OpenSSL 'VMS' shared library method", @@ -101,7 +116,9 @@ static DSO_METHOD dso_meth_vms = { NULL, /* unbind_var */ NULL, /* unbind_func */ #endif - vms_ctrl, + NULL, /* ctrl */ + vms_name_converter, + vms_merger, NULL, /* init */ NULL /* finish */ }; @@ -116,24 +133,47 @@ typedef struct dso_internal_st /* This should contain the name only, no directory, * no extension, nothing but a name. */ struct dsc$descriptor_s filename_dsc; - char filename[FILENAME_MAX+1]; + char filename[ NAMX_MAXRSS+ 1]; /* This contains whatever is not in filename, if needed. * Normally not defined. */ struct dsc$descriptor_s imagename_dsc; - char imagename[FILENAME_MAX+1]; + char imagename[ NAMX_MAXRSS+ 1]; } DSO_VMS_INTERNAL; - DSO_METHOD *DSO_METHOD_vms(void) { return(&dso_meth_vms); } -static int vms_load(DSO *dso, const char *filename) +static int vms_load(DSO *dso) { - DSO_VMS_INTERNAL *p; + void *ptr = NULL; + /* See applicable comments in dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + +/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */ +#if __INITIAL_POINTER_SIZE == 64 +# define DSO_MALLOC _malloc32 +# pragma pointer_size save +# pragma pointer_size 32 +#else /* __INITIAL_POINTER_SIZE == 64 */ +# define DSO_MALLOC OPENSSL_malloc +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + DSO_VMS_INTERNAL *p = NULL; + +#if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +#endif /* __INITIAL_POINTER_SIZE == 64 */ + const char *sp1, *sp2; /* Search result */ + if(filename == NULL) + { + DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME); + goto err; + } + /* A file specification may look like this: * * node::dev:[dir-spec]name.type;ver @@ -175,14 +215,14 @@ static int vms_load(DSO *dso, const char *filename) || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) { DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG); - return(0); + goto err; } - p = (DSO_VMS_INTERNAL *)OPENSSL_malloc(sizeof(DSO_VMS_INTERNAL)); + p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL)); if(p == NULL) { DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE); - return(0); + goto err; } strncpy(p->filename, sp1, sp2-sp1); @@ -201,13 +241,22 @@ static int vms_load(DSO *dso, const char *filename) p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; p->imagename_dsc.dsc$a_pointer = p->imagename; - if(!sk_push(dso->meth_data, (char *)p)) + if(!sk_void_push(dso->meth_data, (char *)p)) { DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR); - OPENSSL_free(p); - return(0); + goto err; } + + /* Success (for now, we lie. We actually do not know...) */ + dso->loaded_filename = filename; return(1); +err: + /* Cleanup! */ + if(p != NULL) + OPENSSL_free(p); + if(filename != NULL) + OPENSSL_free(filename); + return(0); } /* Note that this doesn't actually unload the shared image, as there is no @@ -222,9 +271,9 @@ static int vms_unload(DSO *dso) DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); return(0); } - if(sk_num(dso->meth_data) < 1) + if(sk_void_num(dso->meth_data) < 1) return(1); - p = (DSO_VMS_INTERNAL *)sk_pop(dso->meth_data); + p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data); if(p == NULL) { DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE); @@ -260,30 +309,55 @@ void vms_bind_sym(DSO *dso, const char *symname, void **sym) { DSO_VMS_INTERNAL *ptr; int status; - int flags = LIB$M_FIS_MIXEDCASE; +#if 0 + int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't + defined in VMS older than 7.0 or so */ +#else + int flags = 0; +#endif struct dsc$descriptor_s symname_dsc; - *sym = NULL; - symname_dsc.dsc$w_length = strlen(symname); - symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - symname_dsc.dsc$b_class = DSC$K_CLASS_S; - symname_dsc.dsc$a_pointer = (char *)symname; /* The cast is needed */ +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +#if __INITIAL_POINTER_SIZE == 64 +# define SYMNAME symname_32p +# pragma pointer_size save +# pragma pointer_size 32 + char *symname_32p; +# pragma pointer_size restore + char symname_32[ NAMX_MAXRSS+ 1]; +#else /* __INITIAL_POINTER_SIZE == 64 */ +# define SYMNAME ((char *) symname) +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + *sym = NULL; if((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_VMS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER); return; } - if(sk_num(dso->meth_data) < 1) + +#if __INITIAL_POINTER_SIZE == 64 + /* Copy the symbol name to storage with a 32-bit pointer. */ + symname_32p = symname_32; + strcpy( symname_32p, symname); +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + symname_dsc.dsc$w_length = strlen(SYMNAME); + symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + symname_dsc.dsc$b_class = DSC$K_CLASS_S; + symname_dsc.dsc$a_pointer = SYMNAME; + + if(sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_STACK_ERROR); + DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR); return; } - ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data, - sk_num(dso->meth_data) - 1); + ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data, + sk_void_num(dso->meth_data) - 1); if(ptr == NULL) { - DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_NULL_HANDLE); + DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE); return; } @@ -312,7 +386,7 @@ void vms_bind_sym(DSO *dso, const char *symname, void **sym) { errstring[length] = '\0'; - DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_SYM_FAILURE); + DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE); if (ptr->imagename_dsc.dsc$w_length) ERR_add_error_data(9, "Symbol ", symname, @@ -340,32 +414,112 @@ static void *vms_bind_var(DSO *dso, const char *symname) static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) { DSO_FUNC_TYPE sym = 0; - vms_bind_sym(dso, symname, &sym); + vms_bind_sym(dso, symname, (void **)&sym); return sym; } -static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg) - { - if(dso == NULL) - { - DSOerr(DSO_F_VMS_CTRL,ERR_R_PASSED_NULL_PARAMETER); - return(-1); - } - switch(cmd) - { - case DSO_CTRL_GET_FLAGS: - return dso->flags; - case DSO_CTRL_SET_FLAGS: - dso->flags = (int)larg; - return(0); - case DSO_CTRL_OR_FLAGS: - dso->flags |= (int)larg; - return(0); - default: - break; - } - DSOerr(DSO_F_VMS_CTRL,DSO_R_UNKNOWN_COMMAND); - return(-1); - } - -#endif /* VMS */ + +static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2) + { + int status; + int filespec1len, filespec2len; + struct FAB fab; + struct NAMX_STRUCT nam; + char esa[ NAMX_MAXRSS+ 1]; + char *merged; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +#if __INITIAL_POINTER_SIZE == 64 +# define FILESPEC1 filespec1_32p; +# define FILESPEC2 filespec2_32p; +# pragma pointer_size save +# pragma pointer_size 32 + char *filespec1_32p; + char *filespec2_32p; +# pragma pointer_size restore + char filespec1_32[ NAMX_MAXRSS+ 1]; + char filespec2_32[ NAMX_MAXRSS+ 1]; +#else /* __INITIAL_POINTER_SIZE == 64 */ +# define FILESPEC1 ((char *) filespec1) +# define FILESPEC2 ((char *) filespec2) +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + if (!filespec1) filespec1 = ""; + if (!filespec2) filespec2 = ""; + filespec1len = strlen(filespec1); + filespec2len = strlen(filespec2); + +#if __INITIAL_POINTER_SIZE == 64 + /* Copy the file names to storage with a 32-bit pointer. */ + filespec1_32p = filespec1_32; + filespec2_32p = filespec2_32; + strcpy( filespec1_32p, filespec1); + strcpy( filespec2_32p, filespec2); +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + fab = cc$rms_fab; + nam = CC_RMS_NAMX; + + FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = FILESPEC1; + FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = filespec1len; + FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = FILESPEC2; + FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = filespec2len; + NAMX_DNA_FNA_SET( fab) + + nam.NAMX_ESA = esa; + nam.NAMX_ESS = NAMX_MAXRSS; + nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD; + SET_NAMX_NO_SHORT_UPCASE( nam); + + fab.FAB_NAMX = &nam; + + status = sys$parse(&fab, 0, 0); + + if(!$VMS_STATUS_SUCCESS(status)) + { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else + { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE); + ERR_add_error_data(7, + "filespec \"", filespec1, "\", ", + "defaults \"", filespec2, "\": ", + errstring); + } + return(NULL); + } + + merged = OPENSSL_malloc( nam.NAMX_ESL+ 1); + if(!merged) + goto malloc_err; + strncpy( merged, nam.NAMX_ESA, nam.NAMX_ESL); + merged[ nam.NAMX_ESL] = '\0'; + return(merged); + malloc_err: + DSOerr(DSO_F_VMS_MERGER, + ERR_R_MALLOC_FAILURE); + } + +static char *vms_name_converter(DSO *dso, const char *filename) + { + int len = strlen(filename); + char *not_translated = OPENSSL_malloc(len+1); + strcpy(not_translated,filename); + return(not_translated); + } + +#endif /* OPENSSL_SYS_VMS */