Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/crypto/LPdir_vms.c
34865 views
1
/*
2
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
/*
11
* This file is dual-licensed and is also available under the following
12
* terms:
13
*
14
* Copyright (c) 2004, Richard Levitte <[email protected]>
15
* All rights reserved.
16
*
17
* Redistribution and use in source and binary forms, with or without
18
* modification, are permitted provided that the following conditions
19
* are met:
20
* 1. Redistributions of source code must retain the above copyright
21
* notice, this list of conditions and the following disclaimer.
22
* 2. Redistributions in binary form must reproduce the above copyright
23
* notice, this list of conditions and the following disclaimer in the
24
* documentation and/or other materials provided with the distribution.
25
*
26
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
*/
38
39
#include <stddef.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <errno.h>
43
#include <descrip.h>
44
#include <namdef.h>
45
#include <rmsdef.h>
46
#include <libfildef.h>
47
#include <lib$routines.h>
48
#include <strdef.h>
49
#include <str$routines.h>
50
#include <stsdef.h>
51
#ifndef LPDIR_H
52
# include "LPdir.h"
53
#endif
54
#include "vms_rms.h"
55
56
/* Some compiler options hide EVMSERR. */
57
#ifndef EVMSERR
58
# define EVMSERR 65535 /* error for non-translatable VMS errors */
59
#endif
60
61
struct LP_dir_context_st {
62
unsigned long VMS_context;
63
char filespec[NAMX_MAXRSS + 1];
64
char result[NAMX_MAXRSS + 1];
65
struct dsc$descriptor_d filespec_dsc;
66
struct dsc$descriptor_d result_dsc;
67
};
68
69
const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
70
{
71
int status;
72
char *p, *r;
73
size_t l;
74
unsigned long flags = 0;
75
76
/* Arrange 32-bit pointer to (copied) string storage, if needed. */
77
#if __INITIAL_POINTER_SIZE == 64
78
# pragma pointer_size save
79
# pragma pointer_size 32
80
char *ctx_filespec_32p;
81
# pragma pointer_size restore
82
char ctx_filespec_32[NAMX_MAXRSS + 1];
83
#endif /* __INITIAL_POINTER_SIZE == 64 */
84
85
#ifdef NAML$C_MAXRSS
86
flags |= LIB$M_FIL_LONG_NAMES;
87
#endif
88
89
if (ctx == NULL || directory == NULL) {
90
errno = EINVAL;
91
return 0;
92
}
93
94
errno = 0;
95
if (*ctx == NULL) {
96
size_t filespeclen = strlen(directory);
97
char *filespec = NULL;
98
99
if (filespeclen == 0) {
100
errno = ENOENT;
101
return 0;
102
}
103
104
/* MUST be a VMS directory specification! Let's estimate if it is. */
105
if (directory[filespeclen - 1] != ']'
106
&& directory[filespeclen - 1] != '>'
107
&& directory[filespeclen - 1] != ':') {
108
errno = EINVAL;
109
return 0;
110
}
111
112
filespeclen += 4; /* "*.*;" */
113
114
if (filespeclen > NAMX_MAXRSS) {
115
errno = ENAMETOOLONG;
116
return 0;
117
}
118
119
*ctx = malloc(sizeof(**ctx));
120
if (*ctx == NULL) {
121
errno = ENOMEM;
122
return 0;
123
}
124
memset(*ctx, 0, sizeof(**ctx));
125
126
strcpy((*ctx)->filespec, directory);
127
strcat((*ctx)->filespec, "*.*;");
128
129
/* Arrange 32-bit pointer to (copied) string storage, if needed. */
130
#if __INITIAL_POINTER_SIZE == 64
131
# define CTX_FILESPEC ctx_filespec_32p
132
/* Copy the file name to storage with a 32-bit pointer. */
133
ctx_filespec_32p = ctx_filespec_32;
134
strcpy(ctx_filespec_32p, (*ctx)->filespec);
135
#else /* __INITIAL_POINTER_SIZE == 64 */
136
# define CTX_FILESPEC (*ctx)->filespec
137
#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
138
139
(*ctx)->filespec_dsc.dsc$w_length = filespeclen;
140
(*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
141
(*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
142
(*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
143
}
144
145
(*ctx)->result_dsc.dsc$w_length = 0;
146
(*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
147
(*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
148
(*ctx)->result_dsc.dsc$a_pointer = 0;
149
150
status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
151
&(*ctx)->VMS_context, 0, 0, 0, &flags);
152
153
if (status == RMS$_NMF) {
154
errno = 0;
155
vaxc$errno = status;
156
return NULL;
157
}
158
159
if (!$VMS_STATUS_SUCCESS(status)) {
160
errno = EVMSERR;
161
vaxc$errno = status;
162
return NULL;
163
}
164
165
/*
166
* Quick, cheap and dirty way to discard any device and directory, since
167
* we only want file names
168
*/
169
l = (*ctx)->result_dsc.dsc$w_length;
170
p = (*ctx)->result_dsc.dsc$a_pointer;
171
r = p;
172
for (; *p; p++) {
173
if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */
174
p++;
175
} else if (*p == ':' || *p == '>' || *p == ']') {
176
l -= p + 1 - r;
177
r = p + 1;
178
} else if (*p == ';') {
179
l = p - r;
180
break;
181
}
182
}
183
184
strncpy((*ctx)->result, r, l);
185
(*ctx)->result[l] = '\0';
186
str$free1_dx(&(*ctx)->result_dsc);
187
188
return (*ctx)->result;
189
}
190
191
int LP_find_file_end(LP_DIR_CTX **ctx)
192
{
193
if (ctx != NULL && *ctx != NULL) {
194
int status = lib$find_file_end(&(*ctx)->VMS_context);
195
196
free(*ctx);
197
198
if (!$VMS_STATUS_SUCCESS(status)) {
199
errno = EVMSERR;
200
vaxc$errno = status;
201
return 0;
202
}
203
return 1;
204
}
205
errno = EINVAL;
206
return 0;
207
}
208
209