summaryrefslogtreecommitdiff
path: root/genisoimage/vms.c
diff options
context:
space:
mode:
Diffstat (limited to 'genisoimage/vms.c')
-rw-r--r--genisoimage/vms.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/genisoimage/vms.c b/genisoimage/vms.c
new file mode 100644
index 0000000..9f1c885
--- /dev/null
+++ b/genisoimage/vms.c
@@ -0,0 +1,320 @@
+/*
+ * This file has been modified for the cdrkit suite.
+ *
+ * The behaviour and appearence of the program code below can differ to a major
+ * extent from the version distributed by the original author(s).
+ *
+ * For details, see Changelog file distributed with the cdrkit package. If you
+ * received this file from another source then ask the distributing person for
+ * a log of modifications.
+ *
+ */
+
+/* @(#)vms.c 1.9 04/03/04 joerg */
+/*
+ * File vms.c - assorted bletcherous hacks for VMS.
+ *
+ * Written by Eric Youngdale (1993).
+ *
+ */
+
+#include <mconfig.h>
+#ifdef VMS
+#define opendir fake_opendir
+#include "genisoimage.h"
+#undef opendir
+#include <rms.h>
+#include <descrip.h>
+#include <ssdef.h>
+
+static struct RAB *rab; /* used for external mailfiles */
+static int rms_status;
+
+static
+error_exit(char *text)
+{
+ fprintf(stderr, "%s\n", text);
+ exit(33);
+}
+
+
+char *strrchr(const char *, char);
+
+int
+VMS_stat(char *path, struct stat * spnt)
+{
+ char *spath;
+ char sbuffer[255];
+ char *pnt,
+ *ppnt;
+ char *pnt1;
+
+ ppnt = strrchr(path, ']');
+ if (ppnt)
+ ppnt++;
+ else
+ ppnt = path;
+
+ spath = path;
+
+ if (strcmp(ppnt, ".") == 0 || strcmp(ppnt, "..") == 0) {
+ strcpy(sbuffer, path);
+
+ /* Find end of actual name */
+ pnt = strrchr(sbuffer, ']');
+ if (!pnt)
+ return (0);
+
+ pnt1 = pnt;
+ while (*pnt1 != '[' && *pnt1 != '.')
+ pnt1--;
+
+ if (*pnt1 != '[' && strcmp(ppnt, "..") == 0) {
+ pnt1--;
+ while (*pnt1 != '[' && *pnt1 != '.')
+ pnt1--;
+ };
+
+ if (*pnt1 == '.') {
+ *pnt1 = ']';
+ pnt = pnt1;
+ while (*pnt != '.' && *pnt != ']')
+ pnt++;
+ *pnt++ = ']';
+ while (*pnt != '.' && *pnt != ']')
+ pnt++;
+ *pnt = 0;
+ strcat(sbuffer, ".DIR;1");
+ };
+
+ if (*pnt1 == '[') {
+ pnt1++;
+ *pnt1 = 0;
+ strcat(pnt1, "000000]");
+ pnt1 = strrchr(path, '[') + 1;
+ pnt = sbuffer + strlen(sbuffer);
+ while (*pnt1 && *pnt1 != '.' && *pnt1 != ']')
+ *pnt++ = *pnt1++;
+ *pnt = 0;
+ strcat(sbuffer, ".DIR;1");
+ };
+
+ spath = sbuffer;
+ };
+ return (stat_filter(spath, spnt));
+}
+
+static int dircontext[32] = {0, };
+static char *searchpath[32];
+static struct direct d_entry[32];
+
+int optind = 0;
+char *optarg;
+
+int
+getopt(int argc, char *argv[], char *flags)
+{
+ char *pnt;
+ char c;
+
+ optind++;
+ if (*argv[optind] != '-')
+ return (EOF);
+ optarg = 0;
+
+ c = *(argv[optind] + 1);
+ pnt = (char *) strchr(flags, c);
+ if (!pnt)
+ return (c); /* Not found */
+ if (pnt[1] == ':') {
+ optind++;
+ optarg = argv[optind];
+ };
+ return (c);
+}
+
+void
+vms_path_fixup(char *name)
+{
+ char *pnt1;
+
+ pnt1 = name + strlen(name) - 6;
+
+ /* First strip the .DIR;1 */
+ if (strcmp(pnt1, ".DIR;1") == 0)
+ *pnt1 = 0;
+
+ pnt1 = (char *) strrchr(name, ']');
+ if (pnt1) {
+ if (pnt1[1] == 0)
+ return;
+ *pnt1 = '.';
+ strcat(name, "]");
+ return;
+ };
+ pnt1 = (char *) strrchr(name, '>');
+ if (pnt1) {
+ if (pnt1[1] == 0)
+ return;
+ *pnt1 = '.';
+ strcat(name, ">");
+ return;
+ };
+}
+
+int
+opendir(char *path)
+{
+ int i;
+
+ for (i = 1; i < 32; i++) {
+ if (dircontext[i] == 0) {
+ dircontext[i] = -1;
+ searchpath[i] = (char *) e_malloc(strlen(path) + 6);
+ strcpy(searchpath[i], path);
+ vms_path_fixup(searchpath[i]);
+ strcat(searchpath[i], "*.*.*");
+ return (i);
+ };
+ };
+ exit(0);
+}
+
+struct direct *
+readdir(int context)
+{
+ int i;
+ char cresult[100];
+ char *pnt;
+ int status;
+
+ $DESCRIPTOR(dpath, searchpath[context]);
+ $DESCRIPTOR(result, cresult);
+
+ if (dircontext[context] == -1) {
+ dircontext[context] = -2;
+ strcpy(d_entry[context].d_name, ".");
+ return (&d_entry[context]);
+ };
+
+ if (dircontext[context] == -2) {
+ dircontext[context] = -3;
+ strcpy(d_entry[context].d_name, "..");
+ return (&d_entry[context]);
+ };
+
+ if (dircontext[context] == -3)
+ dircontext[context] = 0;
+
+ dpath.dsc$w_length = strlen(searchpath[context]);
+ lib$find_file(&dpath, &result, &dircontext[context],
+ 0, 0, &status, 0);
+
+ if (status == SS$_NOMOREFILES)
+ return (0);
+
+ /* Now trim trailing spaces from the name */
+ i = result.dsc$w_length - 1;
+ while (i && cresult[i] == ' ')
+ i--;
+ cresult[i + 1] = 0;
+
+ /* Now locate the actual portion of the file we want */
+
+ pnt = (char *) strrchr(cresult, ']');
+ if (pnt)
+ pnt++;
+ else
+ pnt = cresult;
+
+ strcpy(d_entry[context].d_name, pnt);
+ return (&d_entry[context]);
+}
+
+void
+closedir(int context)
+{
+ lib$find_file_end(&dircontext[context]);
+ free(searchpath[context]);
+ searchpath[context] = (char *) 0;
+ dircontext[context] = 0;
+}
+
+static
+open_file(char *fn)
+{
+ /*
+ * this routine initializes a rab and fab required to get the
+ * correct definition of the external data file used by mail
+ */
+ struct FAB *fab;
+
+ rab = (struct RAB *) e_malloc(sizeof (struct RAB));
+ fab = (struct FAB *) e_malloc(sizeof (struct FAB));
+
+ *rab = cc$rms_rab; /* initialize RAB */
+ rab->rab$l_fab = fab;
+
+ *fab = cc$rms_fab; /* initialize FAB */
+ fab->fab$l_fna = fn;
+ fab->fab$b_fns = strlen(fn);
+ fab->fab$w_mrs = 512;
+ fab->fab$b_fac = FAB$M_BIO | FAB$M_GET;
+ fab->fab$b_org = FAB$C_SEQ;
+ fab->fab$b_rfm = FAB$C_FIX;
+ fab->fab$l_xab = (char *) 0;
+
+ rms_status = sys$open(rab->rab$l_fab);
+ if (rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED)
+ error_exit("$OPEN");
+ rms_status = sys$connect(rab);
+ if (rms_status != RMS$_NORMAL)
+ error_exit("$CONNECT");
+ return (1);
+}
+
+static
+close_file(struct RAB * prab)
+{
+ rms_status = sys$close(prab->rab$l_fab);
+ free(prab->rab$l_fab);
+ free(prab);
+ if (rms_status != RMS$_NORMAL)
+ error_exit("$CLOSE");
+}
+
+#define NSECT 16
+extern unsigned int last_extent_written;
+
+int
+vms_write_one_file(char *filename, off_t size, FILE * outfile)
+{
+ int status,
+ i;
+ char buffer[SECTOR_SIZE * NSECT];
+ int count;
+ int use;
+ off_t remain;
+
+ open_file(filename);
+
+ remain = size;
+
+ while (remain > 0) {
+ use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT * SECTOR_SIZE : remain);
+ use = ROUND_UP(use); /* Round up to nearest sector boundary */
+ memset(buffer, 0, use);
+ rab->rab$l_ubf = buffer;
+ rab->rab$w_usz = sizeof (buffer);
+ status = sys$read(rab);
+ fwrite(buffer, 1, use, outfile);
+ last_extent_written += use / SECTOR_SIZE;
+ if ((last_extent_written % 1000) < use / SECTOR_SIZE)
+ fprintf(stderr, "%d..", last_extent_written);
+ remain -= use;
+ };
+
+ close_file(rab);
+}
+
+#endif