314 lines
5.7 KiB
C
314 lines
5.7 KiB
C
|
/* @(#)vms.c 1.11 17/07/17 joerg */
|
||
|
#ifndef lint
|
||
|
static char sccsid[] =
|
||
|
"@(#)vms.c 1.11 17/07/17 joerg";
|
||
|
|
||
|
#endif
|
||
|
/*
|
||
|
* File vms.c - assorted bletcherous hacks for VMS.
|
||
|
*
|
||
|
* Written by Eric Youngdale (1993).
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <schily/mconfig.h>
|
||
|
#ifdef VMS
|
||
|
#define opendir fake_opendir
|
||
|
#include "mkisofs.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 = ISO_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
|