/* * 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 #ifdef VMS #define opendir fake_opendir #include "genisoimage.h" #undef opendir #include #include #include 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