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