summaryrefslogtreecommitdiff
path: root/vms/vmsmunch.c
diff options
context:
space:
mode:
Diffstat (limited to 'vms/vmsmunch.c')
-rw-r--r--vms/vmsmunch.c410
1 files changed, 410 insertions, 0 deletions
diff --git a/vms/vmsmunch.c b/vms/vmsmunch.c
new file mode 100644
index 0000000..b40ef45
--- /dev/null
+++ b/vms/vmsmunch.c
@@ -0,0 +1,410 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#define module_name VMSMUNCH
+#define module_version "V1.3-4"
+/*
+ * Modified by:
+ *
+ * v1.3.1 O.v.d.Linden, C. Spieler 04-JUL-1998 14:35
+ * Modified check that decides on the type of definitions for
+ * FIB$W_FID etc. to support GNU C.
+ *
+ * v1.3 Hunter Goatley 14-SEP-1992 08:51
+ * Added definitions of FIB$W_FID, FIB$W_DID, and
+ * FIB$L_ACCTL to allow for the fact that fibdef
+ * contains variant_unions under Alpha.
+ */
+/*---------------------------------------------------------------------------
+
+ vmsmunch.c version 1.2 28 Apr 1992
+
+ This routine is a blatant and unrepentent appropriation of all the nasty
+ and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
+ so magnificently captured in his FILE utility. Not only that, it's even
+ allowed! (see below). But let it be clear at the outset that Joe did all
+ the work; yea, verily, he is truly a godlike unit.
+
+ The appropriations and modifications herein were performed primarily by
+ him known as "Cave Newt," although the Info-ZIP working group probably had
+ their fingers in it somewhere along the line. The idea is to put the raw
+ power of Joe's original routine at the disposal of various routines used
+ by UnZip (and Zip, possibly), not least among them the utime() function.
+ Read on for details...
+
+ 01-SEP-1994 Richard Levitte <levitte@e.kth.se>
+ If one of the fields given to VMSmunch are NULL,
+ do not update the corresponding daytime.
+
+ 18-JUL-1994 Hunter Goatley <goathunter@WKU.EDU>
+ Fixed IO$_ACCESS call.
+
+ 18-Jul-1994 Richard Levitte levitte@e.kth.se
+ Changed VMSmunch() to deassign the channel before
+ returning when an error has occured.
+
+ 02-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com
+ Moved definition of VMStimbuf struct from here
+ to vmsmunch.h
+ ---------------------------------------------------------------------------
+
+ Usage (i.e., "interface," in geek-speak):
+
+ int VMSmunch( char *filename, int action, char *ptr );
+
+ filename the name of the file on which to be operated, obviously
+ action an integer which specifies what action to take
+ ptr pointer to any extra item which may be needed (else NULL)
+
+ The possible values for the action argument are as follows:
+
+ GET_TIMES get the creation and revision dates of filename; ptr
+ must point to an empty VMStimbuf struct, as defined
+ in vmsmunch.h
+ (with room for at least 24 characters, including term.)
+ SET_TIMES set the creation and revision dates of filename (utime
+ option); ptr must point to a valid VMStimbuf struct,
+ as defined in vmsmunch.h
+ GET_RTYPE get the record type of filename; ptr must point to an
+ integer which, on return, is set to the type (as defined
+ in vmsdefs.h: FAT$C_* defines)
+ CHANGE_RTYPE change the record type to that specified by the integer
+ to which ptr points; save the old record type (later
+ saves overwrite earlier ones)
+ RESTORE_RTYPE restore the record type to the previously saved value;
+ or, if none, set it to "fixed-length, 512-byte" record
+ format (ptr not used)
+
+ ---------------------------------------------------------------------------
+
+ Comments from FILE.C, a utility to modify file characteristics:
+
+ Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
+ BITNET: JOE@FHCRCVAX
+ PHONE: (206) 467-4970
+
+ There are no restrictions on this code, you may sell it, include it
+ with any commercial package, or feed it to a whale.. However, I would
+ appreciate it if you kept this comment in the source code so that anyone
+ receiving this code knows who to contact in case of problems. Note that
+ I do not demand this condition..
+
+ ---------------------------------------------------------------------------*/
+
+
+
+#if defined(__DECC) || defined(__GNUC__)
+#pragma module module_name module_version
+#else
+#module module_name module_version
+#endif
+
+/*****************************/
+/* Includes, Defines, etc. */
+/*****************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <descrip.h>
+#include <rms.h>
+#include <iodef.h>
+#include <starlet.h>
+#include <atrdef.h> /* this gets created with the c3.0 compiler */
+#include <fibdef.h> /* this gets created with the c3.0 compiler */
+
+/*
+ * Under Alpha (DEC C in VAXC mode) and under `good old' VAXC, the FIB unions
+ * are declared as variant_unions. DEC C (Alpha) in ANSI modes and third
+ * party compilers which do not support `variant_union' define preprocessor
+ * symbols to `hide' the "intermediate union/struct" names from the
+ * programmer's API.
+ * We check the presence of these defines and for DEC's FIBDEF.H defining
+ * __union as variant_union to make sure we access the structure correctly.
+ */
+#if defined(fib$w_did) || (defined(__union) && (__union == variant_union))
+# define FIB$W_DID fib$w_did
+# define FIB$W_FID fib$w_fid
+# define FIB$L_ACCTL fib$l_acctl
+#else
+# define FIB$W_DID fib$r_did_overlay.fib$w_did
+# define FIB$W_FID fib$r_fid_overlay.fib$w_fid
+# define FIB$L_ACCTL fib$r_acctl_overlay.fib$l_acctl
+#endif
+
+#include "vmsmunch.h" /* GET/SET_TIMES, RTYPE, etc. */
+#include "vmsdefs.h" /* fatdef.h, etc. */
+
+static void asctim(char *time, long int binval[2]);
+static void bintim(char *time, long int binval[2]);
+
+/* from <ssdef.h> */
+#ifndef SS$_NORMAL
+# define SS$_NORMAL 1
+# define SS$_BADPARAM 20
+#endif
+
+
+/* On VAX, define Goofy VAX Type-Cast to obviate /standard = vaxc.
+ Otherwise, lame system headers on VAX cause compiler warnings.
+ (GNU C may define vax but not __VAX.)
+*/
+#ifdef vax
+# define __VAX 1
+#endif /* def vax */
+
+#ifdef __VAX
+# define GVTC (unsigned int)
+#else /* def __VAX */
+# define GVTC
+#endif /* def __VAX */
+
+
+
+/*************************/
+/* Function VMSmunch() */
+/*************************/
+
+int VMSmunch(
+ char *filename,
+ int action,
+ char *ptr )
+{
+
+ /* original file.c variables */
+
+ static struct FAB Fab;
+ static struct NAM Nam;
+ static struct fibdef Fib; /* short fib */
+
+ static struct dsc$descriptor FibDesc =
+ {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib};
+ static struct dsc$descriptor_s DevDesc =
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
+ static struct fatdef Fat;
+ static union {
+ struct fchdef fch;
+ long int dummy;
+ } uchar;
+ static struct fjndef jnl;
+ static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
+ static short int revisions;
+ static unsigned long uic;
+#if defined(__DECC) || defined(__DECCXX)
+#pragma __member_alignment __save
+#pragma __nomember_alignment
+#endif /* __DECC || __DECCXX */
+ static union {
+ unsigned short int value;
+ struct {
+ unsigned system : 4;
+ unsigned owner : 4;
+ unsigned group : 4;
+ unsigned world : 4;
+ } bits;
+ } prot;
+#if defined(__DECC) || defined(__DECCXX)
+#pragma __member_alignment __restore
+#endif /* __DECC || __DECCXX */
+
+ static struct atrdef Atr[] = {
+ {sizeof(Fat),ATR$C_RECATTR, GVTC &Fat}, /* record attributes */
+ {sizeof(uchar),ATR$C_UCHAR, GVTC &uchar}, /* File characteristics */
+ {sizeof(Cdate),ATR$C_CREDATE, GVTC &Cdate[0]}, /* Creation date */
+ {sizeof(Rdate),ATR$C_REVDATE, GVTC &Rdate[0]}, /* Revision date */
+ {sizeof(Edate),ATR$C_EXPDATE, GVTC &Edate[0]}, /* Expiration date */
+ {sizeof(Bdate),ATR$C_BAKDATE, GVTC &Bdate[0]}, /* Backup date */
+ {sizeof(revisions),ATR$C_ASCDATES, GVTC &revisions}, /* number of revs */
+ {sizeof(prot),ATR$C_FPRO, GVTC &prot}, /* file protection */
+ {sizeof(uic),ATR$C_UIC, GVTC &uic}, /* file owner */
+ {sizeof(jnl),ATR$C_JOURNAL, GVTC &jnl}, /* journal flags */
+ {0,0,0}
+ } ;
+
+ static char EName[NAM$C_MAXRSS];
+ static char RName[NAM$C_MAXRSS];
+ static struct dsc$descriptor_s FileName =
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+ static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+ static short int DevChan;
+ static short int iosb[4];
+
+ static long int i,status;
+/* static char *retval; */
+
+
+ /* new VMSmunch variables */
+
+ static int old_rtype=FAT$C_FIXED; /* storage for record type */
+
+
+
+/*---------------------------------------------------------------------------
+ Initialize attribute blocks, parse filename, resolve any wildcards, and
+ get the file info.
+ ---------------------------------------------------------------------------*/
+
+ /* initialize RMS structures, we need a NAM to retrieve the FID */
+ Fab = cc$rms_fab;
+ Fab.fab$l_fna = filename;
+ Fab.fab$b_fns = strlen(filename);
+ Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
+ Nam = cc$rms_nam;
+ Nam.nam$l_esa = EName; /* expanded filename */
+ Nam.nam$b_ess = sizeof(EName);
+ Nam.nam$l_rsa = RName; /* resultant filename */
+ Nam.nam$b_rss = sizeof(RName);
+
+ /* do $PARSE and $SEARCH here */
+ status = sys$parse(&Fab);
+ if (!(status & 1)) return(status);
+
+ /* search for the first file.. If none signal error */
+ status = sys$search(&Fab);
+ if (!(status & 1)) return(status);
+
+ while (status & 1) {
+ /* initialize Device name length, note that this points into the NAM
+ to get the device name filled in by the $PARSE, $SEARCH services */
+ DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
+
+ status = sys$assign(&DevDesc,&DevChan,0,0);
+ if (!(status & 1)) return(status);
+
+ FileName.dsc$a_pointer = Nam.nam$l_name;
+ FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
+
+ /* Initialize the FIB */
+ for (i=0;i<3;i++) {
+ Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
+ Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
+ }
+
+ /* Use the IO$_ACCESS function to return info about the file */
+ /* Note, used this way, the file is not opened, and the expiration */
+ /* and revision dates are not modified */
+ status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
+ &FibDesc,&FileName,0,0,&Atr,0);
+ if (!(status & 1) || !((status = iosb[0]) & 1)) {
+ sys$dassgn(DevChan);
+ return(status);
+ }
+
+ /*-----------------------------------------------------------------------
+ We have the current information from the file: now see what user
+ wants done with it.
+ -----------------------------------------------------------------------*/
+
+ switch (action) {
+
+ case GET_TIMES: /* non-modifying */
+ asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
+ asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
+ sys$dassgn(DevChan);
+ return RMS$_NORMAL; /* return to user */
+ break;
+
+ case SET_TIMES:
+ if (((struct VMStimbuf *)ptr)->modtime != (char *)NULL)
+ bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
+ if (((struct VMStimbuf *)ptr)->actime != (char *)NULL)
+ bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
+ break;
+
+ case GET_RTYPE: /* non-modifying */
+ *(int *)ptr = Fat.fat$v_rtype;
+ sys$dassgn(DevChan);
+ return RMS$_NORMAL; /* return to user */
+ break;
+
+ case CHANGE_RTYPE:
+ old_rtype = Fat.fat$v_rtype; /* save current one */
+ if ((*(int *)ptr < FAT$C_UNDEFINED) ||
+ (*(int *)ptr > FAT$C_STREAMCR))
+ Fat.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */
+ else
+ Fat.fat$v_rtype = *(int *)ptr;
+ break;
+
+ case RESTORE_RTYPE:
+ Fat.fat$v_rtype = old_rtype;
+ break;
+
+ default:
+ sys$dassgn(DevChan);
+ return SS$_BADPARAM; /* anything better? */
+ }
+
+ /*-----------------------------------------------------------------------
+ Go back and write modified data to the file header.
+ -----------------------------------------------------------------------*/
+
+ /* note, part of the FIB was cleared by earlier QIOW, so reset it */
+ Fib.FIB$L_ACCTL = FIB$M_NORECORD;
+ for (i=0;i<3;i++) {
+ Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
+ Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
+ }
+
+ /* Use the IO$_MODIFY function to change info about the file */
+ /* Note, used this way, the file is not opened, however this would */
+ /* normally cause the expiration and revision dates to be modified. */
+ /* Using FIB$M_NORECORD prohibits this from happening. */
+ status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
+ &FibDesc,&FileName,0,0,&Atr,0);
+ if (!(status & 1) || !((status = iosb[0]) & 1)) {
+ sys$dassgn(DevChan);
+ return(status);
+ }
+
+ status = sys$dassgn(DevChan);
+ if (!(status & 1)) return(status);
+
+ /* look for next file, if none, no big deal.. */
+ status = sys$search(&Fab);
+ }
+ return(status);
+} /* end function VMSmunch() */
+
+
+
+
+
+/***********************/
+/* Function asctim() */
+/***********************/
+
+static void asctim( /* convert 64-bit binval to string, put in time */
+ char *time,
+ long int binval[2] )
+{
+ static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+ /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
+
+ date_str.dsc$a_pointer = time;
+ sys$asctim(0, &date_str, binval, 0);
+ time[23] = '\0';
+}
+
+
+
+
+
+/***********************/
+/* Function bintim() */
+/***********************/
+
+static void bintim( /* convert time string to 64 bits, put in binval */
+ char *time,
+ long int binval[2] )
+{
+ static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+
+ date_str.dsc$w_length = strlen(time);
+ date_str.dsc$a_pointer = time;
+ sys$bintim(&date_str, binval);
+}