diff options
Diffstat (limited to 'genisoimage/vms.c')
-rw-r--r-- | genisoimage/vms.c | 320 |
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 |