2 * This file has been modified for the cdrkit suite.
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).
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.
13 /* @(#)vms.c 1.9 04/03/04 joerg */
15 * File vms.c - assorted bletcherous hacks for VMS.
17 * Written by Eric Youngdale (1993).
23 #define opendir fake_opendir
24 #include "genisoimage.h"
30 static struct RAB *rab; /* used for external mailfiles */
31 static int rms_status;
34 error_exit(char *text)
36 fprintf(stderr, "%s\n", text);
41 char *strrchr(const char *, char);
44 VMS_stat(char *path, struct stat * spnt)
52 ppnt = strrchr(path, ']');
60 if (strcmp(ppnt, ".") == 0 || strcmp(ppnt, "..") == 0) {
61 strcpy(sbuffer, path);
63 /* Find end of actual name */
64 pnt = strrchr(sbuffer, ']');
69 while (*pnt1 != '[' && *pnt1 != '.')
72 if (*pnt1 != '[' && strcmp(ppnt, "..") == 0) {
74 while (*pnt1 != '[' && *pnt1 != '.')
81 while (*pnt != '.' && *pnt != ']')
84 while (*pnt != '.' && *pnt != ']')
87 strcat(sbuffer, ".DIR;1");
93 strcat(pnt1, "000000]");
94 pnt1 = strrchr(path, '[') + 1;
95 pnt = sbuffer + strlen(sbuffer);
96 while (*pnt1 && *pnt1 != '.' && *pnt1 != ']')
99 strcat(sbuffer, ".DIR;1");
104 return (stat_filter(spath, spnt));
107 static int dircontext[32] = {0, };
108 static char *searchpath[32];
109 static struct direct d_entry[32];
115 getopt(int argc, char *argv[], char *flags)
121 if (*argv[optind] != '-')
125 c = *(argv[optind] + 1);
126 pnt = (char *) strchr(flags, c);
128 return (c); /* Not found */
131 optarg = argv[optind];
137 vms_path_fixup(char *name)
141 pnt1 = name + strlen(name) - 6;
143 /* First strip the .DIR;1 */
144 if (strcmp(pnt1, ".DIR;1") == 0)
147 pnt1 = (char *) strrchr(name, ']');
155 pnt1 = (char *) strrchr(name, '>');
170 for (i = 1; i < 32; i++) {
171 if (dircontext[i] == 0) {
173 searchpath[i] = (char *) e_malloc(strlen(path) + 6);
174 strcpy(searchpath[i], path);
175 vms_path_fixup(searchpath[i]);
176 strcat(searchpath[i], "*.*.*");
191 $DESCRIPTOR(dpath, searchpath[context]);
192 $DESCRIPTOR(result, cresult);
194 if (dircontext[context] == -1) {
195 dircontext[context] = -2;
196 strcpy(d_entry[context].d_name, ".");
197 return (&d_entry[context]);
200 if (dircontext[context] == -2) {
201 dircontext[context] = -3;
202 strcpy(d_entry[context].d_name, "..");
203 return (&d_entry[context]);
206 if (dircontext[context] == -3)
207 dircontext[context] = 0;
209 dpath.dsc$w_length = strlen(searchpath[context]);
210 lib$find_file(&dpath, &result, &dircontext[context],
213 if (status == SS$_NOMOREFILES)
216 /* Now trim trailing spaces from the name */
217 i = result.dsc$w_length - 1;
218 while (i && cresult[i] == ' ')
222 /* Now locate the actual portion of the file we want */
224 pnt = (char *) strrchr(cresult, ']');
230 strcpy(d_entry[context].d_name, pnt);
231 return (&d_entry[context]);
235 closedir(int context)
237 lib$find_file_end(&dircontext[context]);
238 free(searchpath[context]);
239 searchpath[context] = (char *) 0;
240 dircontext[context] = 0;
247 * this routine initializes a rab and fab required to get the
248 * correct definition of the external data file used by mail
252 rab = (struct RAB *) e_malloc(sizeof (struct RAB));
253 fab = (struct FAB *) e_malloc(sizeof (struct FAB));
255 *rab = cc$rms_rab; /* initialize RAB */
256 rab->rab$l_fab = fab;
258 *fab = cc$rms_fab; /* initialize FAB */
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;
267 rms_status = sys$open(rab->rab$l_fab);
268 if (rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED)
270 rms_status = sys$connect(rab);
271 if (rms_status != RMS$_NORMAL)
272 error_exit("$CONNECT");
277 close_file(struct RAB * prab)
279 rms_status = sys$close(prab->rab$l_fab);
280 free(prab->rab$l_fab);
282 if (rms_status != RMS$_NORMAL)
283 error_exit("$CLOSE");
287 extern unsigned int last_extent_written;
290 vms_write_one_file(char *filename, off_t size, FILE * outfile)
294 char buffer[SECTOR_SIZE * NSECT];
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);