Category : C Source Code
Archive   : Z201SRC.ZIP
Filename : VMS.C

 
Output of file : VMS.C contained in archive : Z201SRC.ZIP

#ifndef LINT
/* @(#) vms.c 1.4 87/07/26 22:48:45 */
/* @(#) vms.c 2.2 88/01/09 03:47:52 */
#endif /* LINT */

/* machine.c for VMS */

/****************
Date and time functions are standard UNIX-style functions, except that
VAX/VMS does not know about timezones. "nixtime.i" will be included
by machine.c.
*/

#include
#include

/* Function isuadir() returns 1 if the supplied filename is a directory,
else it returns 0.
*/

int isuadir (file)
char *file;
{
struct stat buf; /* buffer to hold file information */
if (stat (file, &buf) == -1) {
return (0); /* inaccessible -- assume not dir */
} else {
if (buf.st_mode & S_IFDIR)
return (1);
else
return (0);
}
}

/****************
Function fixfname() converts the supplied filename to a syntax
legal for the host system. It is used during extraction. We
allow a maximum of one dot in the filename, and it must not
be at the beginning. We also truncate the number of charac-
ters preceding and following the dot to at most 39.
*/

char *strchr();

char *fixfname(fname)
char *fname;
{
char *p;
char *dotpos;
static char legal[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_.0123456789";

/* convert all characters to legal characters */
for (p = fname; *p != '\0'; p++)
if (strchr (legal, *p) == 0) {
if (*p == '-' || *p == ' ')
*p = '_';
else
*p = legal [ *p % 26 ];
}

/* first char can't be dot */
if (*fname == '.')
*fname = 'X';

/* find embedded dot if any */
dotpos = strchr (fname, '.');

if (dotpos != NULL) {
for (p = dotpos+1; *p != '\0'; p++) /* remove 2nd dot onwards */
if (*p == '.')
*p = '_';
if (dotpos - fname + 1 > 39) { /* more than 39 before dot not allowed */
char *q;
p = fname + 39;
q = dotpos;
while (*p++ = *q++) /* the notational convenience is considerable */
;
dotpos = strchr (fname, '.');
}
if (strlen (dotpos + 1) > 39) /* more than 39 after dot not allowed */
*(dotpos + 39 + 1) = '\0';
} else
*(fname + 39) = '\0'; /* no dots, just truncate to 39 characters */
return (fname);
}

/*
Function gettz(), returns the offset from GMT in seconds of the
local time, taking into account daylight savings time -- or it
would, if VAX/VMS knew about timezones! It's just a no-op.
*/
long gettz()
{
return 0L;
}

/* Standard UNIX-compatible time functions */
#include "nixtime.i"

/*
Function utime() is just a stub. VMS C doesn't have it or
an equivalent.
*/
int utime (fname) char *fname; {}

/*
Function unlink() will delete a file using the VMS C delete()
function.
*/
int unlink (fname)
char *fname;
{
return (delete (fname));
}

/*
Function zooexit() receives attempts at exit. It always invokes
exit() with status=1.
*/
int zooexit (status)
int status;
{
exit (1);
}


/*
Function rename() renames a file.
Thanks to Owen Anthony .
*/

#include

#ifndef VMS_RENAME /* if not using VMS 4.6 library rename() */
int rename (new_name, old_name)
char *new_name, *old_name;
{
int status;
struct dsc$descriptor_s file1, file2;
file1.dsc$w_length = strlen (old_name); /* descriptor for old name */
file1.dsc$a_pointer = old_name;
file1.dsc$b_class = DSC$K_CLASS_S;
file1.dsc$b_dtype = DSC$K_DTYPE_T;
file2.dsc$w_length = strlen (new_name); /* descriptor for new name */
file2.dsc$a_pointer = new_name;
file2.dsc$b_class = DSC$K_CLASS_S;
file2.dsc$b_dtype = DSC$K_DTYPE_T;

status = LIB$RENAME_FILE (&file1, &file2);

return ((status & ~1) == 1);
}
#endif /* VMS_RENAME */

/*
Function specfname() modifies filenames before they are stored
in an archive. Currently we remove any trailing version field,
and then any trailing dot.
*/
char *specfname (fname)
char *fname;
{
char *p;
p = strchr (fname, ';');
if (p != NULL)
*p = '\0';
if (*fname != '\0') {
p = fname + strlen (fname) - 1; /* point to last char */
if (*p == '.') /* remove any trailing dot */
*p = '\0';
}
return (fname);
}

/*
Function specdir() modifies directory names before they are stored
in an archive. We remove any leading device name or logical
name and and the [ and ] that bracket any directory name.
Then we change any dots in the directory name to slashes.
*/

#if 0
/* test stub that just truncates dir to null string */
char *specdir (fname) char *fname;
{ *fname = '\0'; return (fname); }
#else

char *specdir (fname)
char *fname;
{
char *p;
char tmpstr[LFNAMESIZE];

p = strchr (fname, ':'); /* remove chars upto and including : */
if (p != NULL) {
strcpy (tmpstr, p+1);
strcpy (fname, tmpstr);
}

p = strchr (fname, '['); /* remove chars upto and including [ */
if (p != NULL) {
strcpy (tmpstr, p+1);
strcpy (fname, tmpstr);
}

p = strchr (fname, ']'); /* truncate at ] */
if (p != NULL) {
if (*(p+1) != '\0')
prterror ('w', "Trailing garbage in directory name\n");
*p = '\0';
}

for (p = fname; *p != '\0'; p++) /* change dots to slashes */
if (*p == '.')
*p = '/';

/* make sure there is a leading slash -- just a hack for now */
if (*fname != '/') {
strcpy (tmpstr, fname);
strcpy (fname, "/");
strcat (fname, tmpstr);
}

#ifdef DEBUG
printf ("dir name transformed to \"%s\"\n", fname);
#endif
}
#endif

#define FMAX 3 /* Number of different filename patterns */

char *nextfile (what, filespec, fileset)
int what; /* whether to initialize or match */
register char *filespec; /* filespec to match if initializing */
register int fileset; /* which set of files */
{
int status;
char *p; /* temp ptr */
struct dsc$descriptor_s d_fwild, d_ffound;
static int first_time [FMAX+1];
static char saved_fspec [FMAX+1][PATHSIZE]; /* our own copy of filespec */
static char found_fspec [FMAX+1][PATHSIZE]; /* matched filename */
static unsigned long context [FMAX+1]; /* needed by VMS */
if (what == 0) {
strcpy (saved_fspec[fileset], filespec); /* save the filespec */
first_time[fileset] = 1;
return (0);
}

/* Reach here if what is not 0, so it must be 1 */

/* Create a descriptor for the wildcarded filespec */
d_fwild.dsc$w_length = strlen (saved_fspec[fileset]);
d_fwild.dsc$a_pointer = saved_fspec[fileset];
d_fwild.dsc$b_class = DSC$K_CLASS_S;
d_fwild.dsc$b_dtype = DSC$K_DTYPE_T;

d_ffound.dsc$w_length = sizeof (found_fspec[fileset]);
d_ffound.dsc$a_pointer = found_fspec[fileset];
d_ffound.dsc$b_class = DSC$K_CLASS_S;
d_ffound.dsc$b_dtype = DSC$K_DTYPE_T;

if (first_time[fileset]) {
first_time[fileset] = 0;
context[fileset] = 0L; /* tell VMS this is first search */
}
status = LIB$FIND_FILE (&d_fwild, &d_ffound, &context[fileset]);
status = status & 1; /* use only lowest bit */

if (status == 0) {
LIB$FIND_FILE_END (&context[fileset]);
return ((char *) 0);
} else {
found_fspec[fileset][d_ffound.dsc$w_length] = '\0'; /* just in case */
p = found_fspec[fileset];
while (*p != ' ' && *p != '\0')
p++;
if (*p != '\0')
*p = '\0';
return (found_fspec[fileset]);
}
}

/*
Function vmsmkdir() converts the received directory name into VMS
format and then creates a directory.
*/
int vmsmkdir (subdir)
char *subdir;
{
char *lastptr();
char *p;
char tmp[LFNAMESIZE];

p = subdir;

/* leading "/" => "[", otherwise => "[." */
if (*p == '/') {
strcpy (tmp, "[");
p++;
} else {
strcpy (tmp, "[.");
while (*p == '/' || *p == '.')
p++;
}

strcat (tmp, p);

/*
VMS doesn't like dots in directory names, so we convert them to
underscores. Leave first two characters untouched, because
we don't want to corrupt a leading "[." into "[_".
*/
for (p = tmp + 2; *p != '\0'; p++)
if (*p == '.')
*p = '_';

/* convert all slashes to dots */
for (p = tmp; *p != '\0'; p++)
if (*p == '/')
*p = '.';

/* Remove any trailing dot */
p = lastptr (tmp);
if (*p == '.')
*p = '\0';

/* append closing bracket */
strcat (tmp, "]");
#if 0
printf ("\nmaking directory \"%s\"\n", tmp);
#endif
return (mkdir (tmp, 0));
}

/*
Function spec_wild() transforms a pattern supplied on the command line into one
suitable for wildcard expansion in the most efficient way possible. We change
each "?" to "%" but let "*" remain unchanged. We also append a ".*" if the
pattern contains no dot, so "*" will be interpreted as "*.*" for VMS globbing.
*/
char *spec_wild (arg)
char *arg;
{
char *p;
#ifdef DEBUG
printf ("spec_wild: arg = [%s]\n", arg);
#endif
if (*lastptr (arg) == ']') /* add *.* if no filename */
strcat (arg, "*.*");
p = nameptr (arg); /* point p to filename part */

/* if no dot in name append ".*" */
if (strchr (p, '.') == NULL)
strcat (p, ".*");

for ( ; *p != '\0'; p++) /* change every "?" to "%" */
if (*p == '?')
*p = '%';
#ifdef DEBUG
printf ("spec_wild: arg changed to [%s]\n", arg);
#endif
return (arg);
}