1 /* @(#)vms.c 1.11 17/07/17 joerg */
2 #ifndef lint
3 static char sccsid[] =
4 "@(#)vms.c 1.11 17/07/17 joerg";
5
6 #endif
7 /*
8 * File vms.c - assorted bletcherous hacks for VMS.
9 *
10 * Written by Eric Youngdale (1993).
11 *
12 */
13
14 #include <schily/mconfig.h>
15 #ifdef VMS
16 #define opendir fake_opendir
17 #include "mkisofs.h"
18 #undef opendir
19 #include <rms.h>
20 #include <descrip.h>
21 #include <ssdef.h>
22
23 static struct RAB *rab; /* used for external mailfiles */
24 static int rms_status;
25
26 static
error_exit(char * text)27 error_exit(char *text)
28 {
29 fprintf(stderr, "%s\n", text);
30 exit(33);
31 }
32
33
34 char *strrchr(const char *, char);
35
36 int
VMS_stat(char * path,struct stat * spnt)37 VMS_stat(char *path, struct stat * spnt)
38 {
39 char *spath;
40 char sbuffer[255];
41 char *pnt,
42 *ppnt;
43 char *pnt1;
44
45 ppnt = strrchr(path, ']');
46 if (ppnt)
47 ppnt++;
48 else
49 ppnt = path;
50
51 spath = path;
52
53 if (strcmp(ppnt, ".") == 0 || strcmp(ppnt, "..") == 0) {
54 strcpy(sbuffer, path);
55
56 /* Find end of actual name */
57 pnt = strrchr(sbuffer, ']');
58 if (!pnt)
59 return (0);
60
61 pnt1 = pnt;
62 while (*pnt1 != '[' && *pnt1 != '.')
63 pnt1--;
64
65 if (*pnt1 != '[' && strcmp(ppnt, "..") == 0) {
66 pnt1--;
67 while (*pnt1 != '[' && *pnt1 != '.')
68 pnt1--;
69 };
70
71 if (*pnt1 == '.') {
72 *pnt1 = ']';
73 pnt = pnt1;
74 while (*pnt != '.' && *pnt != ']')
75 pnt++;
76 *pnt++ = ']';
77 while (*pnt != '.' && *pnt != ']')
78 pnt++;
79 *pnt = 0;
80 strcat(sbuffer, ".DIR;1");
81 };
82
83 if (*pnt1 == '[') {
84 pnt1++;
85 *pnt1 = 0;
86 strcat(pnt1, "000000]");
87 pnt1 = strrchr(path, '[') + 1;
88 pnt = sbuffer + strlen(sbuffer);
89 while (*pnt1 && *pnt1 != '.' && *pnt1 != ']')
90 *pnt++ = *pnt1++;
91 *pnt = 0;
92 strcat(sbuffer, ".DIR;1");
93 };
94
95 spath = sbuffer;
96 };
97 return (stat_filter(spath, spnt));
98 }
99
100 static int dircontext[32] = {0, };
101 static char *searchpath[32];
102 static struct direct d_entry[32];
103
104 int optind = 0;
105 char *optarg;
106
107 int
getopt(int argc,char * argv[],char * flags)108 getopt(int argc, char *argv[], char *flags)
109 {
110 char *pnt;
111 char c;
112
113 optind++;
114 if (*argv[optind] != '-')
115 return (EOF);
116 optarg = 0;
117
118 c = *(argv[optind] + 1);
119 pnt = (char *) strchr(flags, c);
120 if (!pnt)
121 return (c); /* Not found */
122 if (pnt[1] == ':') {
123 optind++;
124 optarg = argv[optind];
125 };
126 return (c);
127 }
128
129 void
vms_path_fixup(char * name)130 vms_path_fixup(char *name)
131 {
132 char *pnt1;
133
134 pnt1 = name + strlen(name) - 6;
135
136 /* First strip the .DIR;1 */
137 if (strcmp(pnt1, ".DIR;1") == 0)
138 *pnt1 = 0;
139
140 pnt1 = (char *) strrchr(name, ']');
141 if (pnt1) {
142 if (pnt1[1] == 0)
143 return;
144 *pnt1 = '.';
145 strcat(name, "]");
146 return;
147 };
148 pnt1 = (char *) strrchr(name, '>');
149 if (pnt1) {
150 if (pnt1[1] == 0)
151 return;
152 *pnt1 = '.';
153 strcat(name, ">");
154 return;
155 };
156 }
157
158 int
opendir(char * path)159 opendir(char *path)
160 {
161 int i;
162
163 for (i = 1; i < 32; i++) {
164 if (dircontext[i] == 0) {
165 dircontext[i] = -1;
166 searchpath[i] = (char *) e_malloc(strlen(path) + 6);
167 strcpy(searchpath[i], path);
168 vms_path_fixup(searchpath[i]);
169 strcat(searchpath[i], "*.*.*");
170 return (i);
171 };
172 };
173 exit(0);
174 }
175
176 struct direct *
readdir(int context)177 readdir(int context)
178 {
179 int i;
180 char cresult[100];
181 char *pnt;
182 int status;
183
184 $DESCRIPTOR(dpath, searchpath[context]);
185 $DESCRIPTOR(result, cresult);
186
187 if (dircontext[context] == -1) {
188 dircontext[context] = -2;
189 strcpy(d_entry[context].d_name, ".");
190 return (&d_entry[context]);
191 };
192
193 if (dircontext[context] == -2) {
194 dircontext[context] = -3;
195 strcpy(d_entry[context].d_name, "..");
196 return (&d_entry[context]);
197 };
198
199 if (dircontext[context] == -3)
200 dircontext[context] = 0;
201
202 dpath.dsc$w_length = strlen(searchpath[context]);
203 lib$find_file(&dpath, &result, &dircontext[context],
204 0, 0, &status, 0);
205
206 if (status == SS$_NOMOREFILES)
207 return (0);
208
209 /* Now trim trailing spaces from the name */
210 i = result.dsc$w_length - 1;
211 while (i && cresult[i] == ' ')
212 i--;
213 cresult[i + 1] = 0;
214
215 /* Now locate the actual portion of the file we want */
216
217 pnt = (char *) strrchr(cresult, ']');
218 if (pnt)
219 pnt++;
220 else
221 pnt = cresult;
222
223 strcpy(d_entry[context].d_name, pnt);
224 return (&d_entry[context]);
225 }
226
227 void
closedir(int context)228 closedir(int context)
229 {
230 lib$find_file_end(&dircontext[context]);
231 free(searchpath[context]);
232 searchpath[context] = (char *) 0;
233 dircontext[context] = 0;
234 }
235
236 static
open_file(char * fn)237 open_file(char *fn)
238 {
239 /*
240 * this routine initializes a rab and fab required to get the
241 * correct definition of the external data file used by mail
242 */
243 struct FAB *fab;
244
245 rab = (struct RAB *) e_malloc(sizeof (struct RAB));
246 fab = (struct FAB *) e_malloc(sizeof (struct FAB));
247
248 *rab = cc$rms_rab; /* initialize RAB */
249 rab->rab$l_fab = fab;
250
251 *fab = cc$rms_fab; /* initialize FAB */
252 fab->fab$l_fna = fn;
253 fab->fab$b_fns = strlen(fn);
254 fab->fab$w_mrs = 512;
255 fab->fab$b_fac = FAB$M_BIO | FAB$M_GET;
256 fab->fab$b_org = FAB$C_SEQ;
257 fab->fab$b_rfm = FAB$C_FIX;
258 fab->fab$l_xab = (char *) 0;
259
260 rms_status = sys$open(rab->rab$l_fab);
261 if (rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED)
262 error_exit("$OPEN");
263 rms_status = sys$connect(rab);
264 if (rms_status != RMS$_NORMAL)
265 error_exit("$CONNECT");
266 return (1);
267 }
268
269 static
close_file(struct RAB * prab)270 close_file(struct RAB * prab)
271 {
272 rms_status = sys$close(prab->rab$l_fab);
273 free(prab->rab$l_fab);
274 free(prab);
275 if (rms_status != RMS$_NORMAL)
276 error_exit("$CLOSE");
277 }
278
279 #define NSECT 16
280 extern unsigned int last_extent_written;
281
282 int
vms_write_one_file(char * filename,off_t size,FILE * outfile)283 vms_write_one_file(char *filename, off_t size, FILE * outfile)
284 {
285 int status,
286 i;
287 char buffer[SECTOR_SIZE * NSECT];
288 int count;
289 int use;
290 off_t remain;
291
292 open_file(filename);
293
294 remain = size;
295
296 while (remain > 0) {
297 use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT * SECTOR_SIZE : remain);
298 use = ISO_ROUND_UP(use); /* Round up to nearest sector boundary */
299 memset(buffer, 0, use);
300 rab->rab$l_ubf = buffer;
301 rab->rab$w_usz = sizeof (buffer);
302 status = sys$read(rab);
303 fwrite(buffer, 1, use, outfile);
304 last_extent_written += use / SECTOR_SIZE;
305 if ((last_extent_written % 1000) < use / SECTOR_SIZE)
306 fprintf(stderr, "%d..", last_extent_written);
307 remain -= use;
308 };
309
310 close_file(rab);
311 }
312
313 #endif
314