]>
Commit | Line | Data |
---|---|---|
cbecb3ac | 1 | /* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */ |
0e05f545 RL |
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL |
3 | * project 2000. | |
4 | */ | |
5 | /* ==================================================================== | |
6 | * Copyright (c) 2000 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <stdio.h> | |
60 | #include <string.h> | |
61 | #include <errno.h> | |
03c4d82f RL |
62 | #include "cryptlib.h" |
63 | #include <openssl/dso.h> | |
804ab36d GT |
64 | |
65 | #ifndef OPENSSL_SYS_VMS | |
66 | DSO_METHOD *DSO_METHOD_vms(void) | |
67 | { | |
68 | return NULL; | |
69 | } | |
70 | #else | |
71 | ||
3aa477f6 | 72 | #pragma message disable DOLLARID |
cbecb3ac | 73 | #include <rms.h> |
0e05f545 | 74 | #include <lib$routines.h> |
0e05f545 RL |
75 | #include <stsdef.h> |
76 | #include <descrip.h> | |
77 | #include <starlet.h> | |
01d2e27a RL |
78 | #include "vms_rms.h" |
79 | ||
80 | /* Some compiler options may mask the declaration of "_malloc32". */ | |
81 | #if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE | |
82 | # if __INITIAL_POINTER_SIZE == 64 | |
83 | # pragma pointer_size save | |
84 | # pragma pointer_size 32 | |
85 | void * _malloc32 (__size_t); | |
86 | # pragma pointer_size restore | |
87 | # endif /* __INITIAL_POINTER_SIZE == 64 */ | |
88 | #endif /* __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE */ | |
89 | ||
0e05f545 | 90 | |
0e05f545 RL |
91 | #pragma message disable DOLLARID |
92 | ||
51c8dc37 | 93 | static int vms_load(DSO *dso); |
0e05f545 RL |
94 | static int vms_unload(DSO *dso); |
95 | static void *vms_bind_var(DSO *dso, const char *symname); | |
96 | static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); | |
97 | #if 0 | |
98 | static int vms_unbind_var(DSO *dso, char *symname, void *symptr); | |
99 | static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); | |
100 | static int vms_init(DSO *dso); | |
101 | static int vms_finish(DSO *dso); | |
0e05f545 | 102 | static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); |
75a382bd | 103 | #endif |
03c4d82f | 104 | static char *vms_name_converter(DSO *dso, const char *filename); |
cbecb3ac RL |
105 | static char *vms_merger(DSO *dso, const char *filespec1, |
106 | const char *filespec2); | |
0e05f545 RL |
107 | |
108 | static DSO_METHOD dso_meth_vms = { | |
109 | "OpenSSL 'VMS' shared library method", | |
110 | vms_load, | |
111 | NULL, /* unload */ | |
112 | vms_bind_var, | |
113 | vms_bind_func, | |
114 | /* For now, "unbind" doesn't exist */ | |
115 | #if 0 | |
116 | NULL, /* unbind_var */ | |
117 | NULL, /* unbind_func */ | |
118 | #endif | |
75a382bd | 119 | NULL, /* ctrl */ |
51c8dc37 | 120 | vms_name_converter, |
cbecb3ac | 121 | vms_merger, |
0e05f545 RL |
122 | NULL, /* init */ |
123 | NULL /* finish */ | |
124 | }; | |
125 | ||
126 | /* On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends | |
127 | * on the reference to the file name being the same for all calls regarding | |
128 | * one shared image, so we'll just store it in an instance of the following | |
129 | * structure and put a pointer to that instance in the meth_data stack. | |
130 | */ | |
131 | typedef struct dso_internal_st | |
132 | { | |
133 | /* This should contain the name only, no directory, | |
134 | * no extension, nothing but a name. */ | |
135 | struct dsc$descriptor_s filename_dsc; | |
01d2e27a | 136 | char filename[ NAMX_MAXRSS+ 1]; |
0e05f545 RL |
137 | /* This contains whatever is not in filename, if needed. |
138 | * Normally not defined. */ | |
139 | struct dsc$descriptor_s imagename_dsc; | |
01d2e27a | 140 | char imagename[ NAMX_MAXRSS+ 1]; |
0e05f545 RL |
141 | } DSO_VMS_INTERNAL; |
142 | ||
0e05f545 RL |
143 | DSO_METHOD *DSO_METHOD_vms(void) |
144 | { | |
145 | return(&dso_meth_vms); | |
146 | } | |
147 | ||
51c8dc37 | 148 | static int vms_load(DSO *dso) |
0e05f545 | 149 | { |
856d456a RL |
150 | void *ptr = NULL; |
151 | /* See applicable comments in dso_dl.c */ | |
152 | char *filename = DSO_convert_filename(dso, NULL); | |
01d2e27a RL |
153 | |
154 | /* Ensure 32-bit pointer for "p", and appropriate malloc() function. */ | |
155 | #if __INITIAL_POINTER_SIZE == 64 | |
156 | # define DSO_MALLOC _malloc32 | |
157 | # pragma pointer_size save | |
158 | # pragma pointer_size 32 | |
159 | #else /* __INITIAL_POINTER_SIZE == 64 */ | |
160 | # define DSO_MALLOC OPENSSL_malloc | |
161 | #endif /* __INITIAL_POINTER_SIZE == 64 [else] */ | |
162 | ||
be085335 | 163 | DSO_VMS_INTERNAL *p = NULL; |
01d2e27a RL |
164 | |
165 | #if __INITIAL_POINTER_SIZE == 64 | |
166 | # pragma pointer_size restore | |
167 | #endif /* __INITIAL_POINTER_SIZE == 64 */ | |
168 | ||
0e05f545 RL |
169 | const char *sp1, *sp2; /* Search result */ |
170 | ||
856d456a RL |
171 | if(filename == NULL) |
172 | { | |
aa4ce731 | 173 | DSOerr(DSO_F_VMS_LOAD,DSO_R_NO_FILENAME); |
856d456a RL |
174 | goto err; |
175 | } | |
176 | ||
3e9a08ec TH |
177 | /*- |
178 | * A file specification may look like this: | |
0e05f545 RL |
179 | * |
180 | * node::dev:[dir-spec]name.type;ver | |
181 | * | |
182 | * or (for compatibility with TOPS-20): | |
183 | * | |
184 | * node::dev:<dir-spec>name.type;ver | |
185 | * | |
186 | * and the dir-spec uses '.' as separator. Also, a dir-spec | |
187 | * may consist of several parts, with mixed use of [] and <>: | |
188 | * | |
189 | * [dir1.]<dir2> | |
190 | * | |
191 | * We need to split the file specification into the name and | |
192 | * the rest (both before and after the name itself). | |
193 | */ | |
194 | /* Start with trying to find the end of a dir-spec, and save the | |
195 | position of the byte after in sp1 */ | |
196 | sp1 = strrchr(filename, ']'); | |
197 | sp2 = strrchr(filename, '>'); | |
198 | if (sp1 == NULL) sp1 = sp2; | |
199 | if (sp2 != NULL && sp2 > sp1) sp1 = sp2; | |
200 | if (sp1 == NULL) sp1 = strrchr(filename, ':'); | |
201 | if (sp1 == NULL) | |
202 | sp1 = filename; | |
203 | else | |
204 | sp1++; /* The byte after the found character */ | |
205 | /* Now, let's see if there's a type, and save the position in sp2 */ | |
206 | sp2 = strchr(sp1, '.'); | |
207 | /* If we found it, that's where we'll cut. Otherwise, look for a | |
208 | version number and save the position in sp2 */ | |
209 | if (sp2 == NULL) sp2 = strchr(sp1, ';'); | |
210 | /* If there was still nothing to find, set sp2 to point at the end of | |
211 | the string */ | |
212 | if (sp2 == NULL) sp2 = sp1 + strlen(sp1); | |
213 | ||
214 | /* Check that we won't get buffer overflows */ | |
215 | if (sp2 - sp1 > FILENAME_MAX | |
216 | || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) | |
217 | { | |
218 | DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG); | |
856d456a | 219 | goto err; |
0e05f545 RL |
220 | } |
221 | ||
01d2e27a | 222 | p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL)); |
0e05f545 RL |
223 | if(p == NULL) |
224 | { | |
225 | DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE); | |
856d456a | 226 | goto err; |
0e05f545 RL |
227 | } |
228 | ||
229 | strncpy(p->filename, sp1, sp2-sp1); | |
230 | p->filename[sp2-sp1] = '\0'; | |
231 | ||
232 | strncpy(p->imagename, filename, sp1-filename); | |
233 | p->imagename[sp1-filename] = '\0'; | |
234 | strcat(p->imagename, sp2); | |
235 | ||
236 | p->filename_dsc.dsc$w_length = strlen(p->filename); | |
237 | p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; | |
238 | p->filename_dsc.dsc$b_class = DSC$K_CLASS_S; | |
239 | p->filename_dsc.dsc$a_pointer = p->filename; | |
240 | p->imagename_dsc.dsc$w_length = strlen(p->imagename); | |
241 | p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; | |
242 | p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; | |
243 | p->imagename_dsc.dsc$a_pointer = p->imagename; | |
244 | ||
e77228ba | 245 | if(!sk_void_push(dso->meth_data, (char *)p)) |
0e05f545 RL |
246 | { |
247 | DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR); | |
856d456a | 248 | goto err; |
0e05f545 | 249 | } |
856d456a RL |
250 | |
251 | /* Success (for now, we lie. We actually do not know...) */ | |
252 | dso->loaded_filename = filename; | |
0e05f545 | 253 | return(1); |
856d456a RL |
254 | err: |
255 | /* Cleanup! */ | |
256 | if(p != NULL) | |
257 | OPENSSL_free(p); | |
258 | if(filename != NULL) | |
259 | OPENSSL_free(filename); | |
260 | return(0); | |
0e05f545 RL |
261 | } |
262 | ||
263 | /* Note that this doesn't actually unload the shared image, as there is no | |
264 | * such thing in VMS. Next time it get loaded again, a new copy will | |
265 | * actually be loaded. | |
266 | */ | |
267 | static int vms_unload(DSO *dso) | |
268 | { | |
269 | DSO_VMS_INTERNAL *p; | |
270 | if(dso == NULL) | |
271 | { | |
272 | DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); | |
273 | return(0); | |
274 | } | |
e77228ba | 275 | if(sk_void_num(dso->meth_data) < 1) |
0e05f545 | 276 | return(1); |
e77228ba | 277 | p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data); |
0e05f545 RL |
278 | if(p == NULL) |
279 | { | |
280 | DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE); | |
281 | return(0); | |
282 | } | |
283 | /* Cleanup */ | |
284 | OPENSSL_free(p); | |
285 | return(1); | |
286 | } | |
287 | ||
288 | /* We must do this in a separate function because of the way the exception | |
289 | handler works (it makes this function return */ | |
290 | static int do_find_symbol(DSO_VMS_INTERNAL *ptr, | |
291 | struct dsc$descriptor_s *symname_dsc, void **sym, | |
292 | unsigned long flags) | |
293 | { | |
294 | /* Make sure that signals are caught and returned instead of | |
295 | aborting the program. The exception handler gets unestablished | |
296 | automatically on return from this function. */ | |
297 | lib$establish(lib$sig_to_ret); | |
298 | ||
299 | if(ptr->imagename_dsc.dsc$w_length) | |
300 | return lib$find_image_symbol(&ptr->filename_dsc, | |
301 | symname_dsc, sym, | |
302 | &ptr->imagename_dsc, flags); | |
303 | else | |
304 | return lib$find_image_symbol(&ptr->filename_dsc, | |
305 | symname_dsc, sym, | |
306 | 0, flags); | |
307 | } | |
308 | ||
3aa477f6 | 309 | void vms_bind_sym(DSO *dso, const char *symname, void **sym) |
0e05f545 RL |
310 | { |
311 | DSO_VMS_INTERNAL *ptr; | |
0e05f545 | 312 | int status; |
9d93ce24 | 313 | #if 0 |
e56b54a3 RL |
314 | int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't |
315 | defined in VMS older than 7.0 or so */ | |
9d93ce24 RL |
316 | #else |
317 | int flags = 0; | |
318 | #endif | |
0e05f545 RL |
319 | struct dsc$descriptor_s symname_dsc; |
320 | ||
01d2e27a RL |
321 | /* Arrange 32-bit pointer to (copied) string storage, if needed. */ |
322 | #if __INITIAL_POINTER_SIZE == 64 | |
323 | # define SYMNAME symname_32p | |
324 | # pragma pointer_size save | |
325 | # pragma pointer_size 32 | |
326 | char *symname_32p; | |
327 | # pragma pointer_size restore | |
328 | char symname_32[ NAMX_MAXRSS+ 1]; | |
329 | #else /* __INITIAL_POINTER_SIZE == 64 */ | |
330 | # define SYMNAME ((char *) symname) | |
331 | #endif /* __INITIAL_POINTER_SIZE == 64 [else] */ | |
332 | ||
333 | *sym = NULL; | |
0e05f545 RL |
334 | |
335 | if((dso == NULL) || (symname == NULL)) | |
336 | { | |
aa4ce731 | 337 | DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER); |
3aa477f6 | 338 | return; |
0e05f545 | 339 | } |
01d2e27a RL |
340 | |
341 | #if __INITIAL_POINTER_SIZE == 64 | |
342 | /* Copy the symbol name to storage with a 32-bit pointer. */ | |
343 | symname_32p = symname_32; | |
344 | strcpy( symname_32p, symname); | |
345 | #endif /* __INITIAL_POINTER_SIZE == 64 [else] */ | |
346 | ||
347 | symname_dsc.dsc$w_length = strlen(SYMNAME); | |
348 | symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; | |
349 | symname_dsc.dsc$b_class = DSC$K_CLASS_S; | |
350 | symname_dsc.dsc$a_pointer = SYMNAME; | |
351 | ||
e77228ba | 352 | if(sk_void_num(dso->meth_data) < 1) |
0e05f545 | 353 | { |
aa4ce731 | 354 | DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR); |
3aa477f6 | 355 | return; |
0e05f545 | 356 | } |
e77228ba RL |
357 | ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data, |
358 | sk_void_num(dso->meth_data) - 1); | |
0e05f545 RL |
359 | if(ptr == NULL) |
360 | { | |
aa4ce731 | 361 | DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE); |
3aa477f6 | 362 | return; |
0e05f545 RL |
363 | } |
364 | ||
365 | if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0; | |
366 | ||
3aa477f6 | 367 | status = do_find_symbol(ptr, &symname_dsc, sym, flags); |
0e05f545 RL |
368 | |
369 | if(!$VMS_STATUS_SUCCESS(status)) | |
370 | { | |
371 | unsigned short length; | |
372 | char errstring[257]; | |
373 | struct dsc$descriptor_s errstring_dsc; | |
374 | ||
375 | errstring_dsc.dsc$w_length = sizeof(errstring); | |
376 | errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; | |
377 | errstring_dsc.dsc$b_class = DSC$K_CLASS_S; | |
378 | errstring_dsc.dsc$a_pointer = errstring; | |
379 | ||
3aa477f6 RL |
380 | *sym = NULL; |
381 | ||
0e05f545 RL |
382 | status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); |
383 | ||
384 | if (!$VMS_STATUS_SUCCESS(status)) | |
385 | lib$signal(status); /* This is really bad. Abort! */ | |
386 | else | |
387 | { | |
388 | errstring[length] = '\0'; | |
389 | ||
aa4ce731 | 390 | DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE); |
0e05f545 RL |
391 | if (ptr->imagename_dsc.dsc$w_length) |
392 | ERR_add_error_data(9, | |
393 | "Symbol ", symname, | |
394 | " in ", ptr->filename, | |
395 | " (", ptr->imagename, ")", | |
396 | ": ", errstring); | |
397 | else | |
398 | ERR_add_error_data(6, | |
399 | "Symbol ", symname, | |
400 | " in ", ptr->filename, | |
401 | ": ", errstring); | |
402 | } | |
3aa477f6 | 403 | return; |
0e05f545 | 404 | } |
3aa477f6 | 405 | return; |
0e05f545 RL |
406 | } |
407 | ||
408 | static void *vms_bind_var(DSO *dso, const char *symname) | |
409 | { | |
3aa477f6 RL |
410 | void *sym = 0; |
411 | vms_bind_sym(dso, symname, &sym); | |
412 | return sym; | |
0e05f545 RL |
413 | } |
414 | ||
415 | static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) | |
416 | { | |
3aa477f6 | 417 | DSO_FUNC_TYPE sym = 0; |
4534fb1c | 418 | vms_bind_sym(dso, symname, (void **)&sym); |
3aa477f6 | 419 | return sym; |
0e05f545 RL |
420 | } |
421 | ||
01d2e27a | 422 | |
cbecb3ac RL |
423 | static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2) |
424 | { | |
425 | int status; | |
426 | int filespec1len, filespec2len; | |
427 | struct FAB fab; | |
01d2e27a RL |
428 | struct NAMX_STRUCT nam; |
429 | char esa[ NAMX_MAXRSS+ 1]; | |
cbecb3ac RL |
430 | char *merged; |
431 | ||
01d2e27a RL |
432 | /* Arrange 32-bit pointer to (copied) string storage, if needed. */ |
433 | #if __INITIAL_POINTER_SIZE == 64 | |
434 | # define FILESPEC1 filespec1_32p; | |
435 | # define FILESPEC2 filespec2_32p; | |
436 | # pragma pointer_size save | |
437 | # pragma pointer_size 32 | |
438 | char *filespec1_32p; | |
439 | char *filespec2_32p; | |
440 | # pragma pointer_size restore | |
441 | char filespec1_32[ NAMX_MAXRSS+ 1]; | |
442 | char filespec2_32[ NAMX_MAXRSS+ 1]; | |
443 | #else /* __INITIAL_POINTER_SIZE == 64 */ | |
444 | # define FILESPEC1 ((char *) filespec1) | |
445 | # define FILESPEC2 ((char *) filespec2) | |
446 | #endif /* __INITIAL_POINTER_SIZE == 64 [else] */ | |
447 | ||
cbecb3ac RL |
448 | if (!filespec1) filespec1 = ""; |
449 | if (!filespec2) filespec2 = ""; | |
450 | filespec1len = strlen(filespec1); | |
451 | filespec2len = strlen(filespec2); | |
452 | ||
01d2e27a RL |
453 | #if __INITIAL_POINTER_SIZE == 64 |
454 | /* Copy the file names to storage with a 32-bit pointer. */ | |
455 | filespec1_32p = filespec1_32; | |
456 | filespec2_32p = filespec2_32; | |
457 | strcpy( filespec1_32p, filespec1); | |
458 | strcpy( filespec2_32p, filespec2); | |
459 | #endif /* __INITIAL_POINTER_SIZE == 64 [else] */ | |
460 | ||
cbecb3ac | 461 | fab = cc$rms_fab; |
01d2e27a | 462 | nam = CC_RMS_NAMX; |
cbecb3ac | 463 | |
01d2e27a RL |
464 | FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = FILESPEC1; |
465 | FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = filespec1len; | |
466 | FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = FILESPEC2; | |
467 | FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = filespec2len; | |
468 | NAMX_DNA_FNA_SET( fab) | |
469 | ||
470 | nam.NAMX_ESA = esa; | |
471 | nam.NAMX_ESS = NAMX_MAXRSS; | |
472 | nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD; | |
473 | SET_NAMX_NO_SHORT_UPCASE( nam); | |
474 | ||
475 | fab.FAB_NAMX = &nam; | |
cbecb3ac RL |
476 | |
477 | status = sys$parse(&fab, 0, 0); | |
478 | ||
479 | if(!$VMS_STATUS_SUCCESS(status)) | |
480 | { | |
481 | unsigned short length; | |
482 | char errstring[257]; | |
483 | struct dsc$descriptor_s errstring_dsc; | |
484 | ||
485 | errstring_dsc.dsc$w_length = sizeof(errstring); | |
486 | errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; | |
487 | errstring_dsc.dsc$b_class = DSC$K_CLASS_S; | |
488 | errstring_dsc.dsc$a_pointer = errstring; | |
489 | ||
cbecb3ac RL |
490 | status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); |
491 | ||
492 | if (!$VMS_STATUS_SUCCESS(status)) | |
493 | lib$signal(status); /* This is really bad. Abort! */ | |
494 | else | |
495 | { | |
496 | errstring[length] = '\0'; | |
497 | ||
498 | DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE); | |
7a5ed919 RL |
499 | ERR_add_error_data(7, |
500 | "filespec \"", filespec1, "\", ", | |
501 | "defaults \"", filespec2, "\": ", | |
502 | errstring); | |
cbecb3ac RL |
503 | } |
504 | return(NULL); | |
505 | } | |
01d2e27a RL |
506 | |
507 | merged = OPENSSL_malloc( nam.NAMX_ESL+ 1); | |
cbecb3ac RL |
508 | if(!merged) |
509 | goto malloc_err; | |
01d2e27a RL |
510 | strncpy( merged, nam.NAMX_ESA, nam.NAMX_ESL); |
511 | merged[ nam.NAMX_ESL] = '\0'; | |
cbecb3ac RL |
512 | return(merged); |
513 | malloc_err: | |
514 | DSOerr(DSO_F_VMS_MERGER, | |
515 | ERR_R_MALLOC_FAILURE); | |
516 | } | |
517 | ||
856d456a | 518 | static char *vms_name_converter(DSO *dso, const char *filename) |
51c8dc37 | 519 | { |
03c4d82f RL |
520 | int len = strlen(filename); |
521 | char *not_translated = OPENSSL_malloc(len+1); | |
522 | strcpy(not_translated,filename); | |
523 | return(not_translated); | |
51c8dc37 GT |
524 | } |
525 | ||
bc36ee62 | 526 | #endif /* OPENSSL_SYS_VMS */ |