1 /*---------------------------------------------------------------------------
3 VMSmunch.c version 1.3 28 Apr 1992
5 This routine is a blatant and unrepentent appropriation of all the nasty
6 and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
7 so magnificently captured in his FILE utility. Not only that, it's even
8 allowed! (see below). But let it be clear at the outset that Joe did all
9 the work; yea, verily, he is truly a godlike unit.
11 The appropriations and modifications herein were performed primarily by
12 him known as "Cave Newt," although the Info-ZIP working group probably had
13 their fingers in it somewhere along the line. The idea is to put the raw
14 power of Joe's original routine at the disposal of various routines used
15 by UnZip (and Zip, possibly), not least among them the utime() function.
16 Read on for details...
18 18-JUL-1994 Hunter Goatley <goathunter@WKU.EDU>
19 Fixed IO$_ACCESS call.
21 18-Jul-1994 Richard Levitte levitte@e.kth.se
22 Changed VMSmunch() to deassign the channel before
23 returning when an error has occured.
25 02-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com
26 Moved definition of VMStimbuf struct from here
28 ---------------------------------------------------------------------------
30 Usage (i.e., "interface," in geek-speak):
32 int VMSmunch( char *filename, int action, char *ptr );
34 filename the name of the file on which to be operated, obviously
35 action an integer which specifies what action to take
36 ptr pointer to any extra item which may be needed (else NULL)
38 The possible values for the action argument are as follows:
40 GET_TIMES get the creation and revision dates of filename; ptr
41 must point to an empty VMStimbuf struct, as defined
43 (with room for at least 24 characters, including term.)
44 SET_TIMES set the creation and revision dates of filename (utime
45 option); ptr must point to a valid VMStimbuf struct,
46 as defined in vmsmunch.h
47 GET_RTYPE get the record type of filename; ptr must point to an
48 integer which, on return, is set to the type (as defined
49 in VMSmunch.h: FAT$C_* defines)
50 CHANGE_RTYPE change the record type to that specified by the integer
51 to which ptr points; save the old record type (later
52 saves overwrite earlier ones)
53 RESTORE_RTYPE restore the record type to the previously saved value;
54 or, if none, set it to "fixed-length, 512-byte" record
57 ---------------------------------------------------------------------------
59 Comments from FILE.C, a utility to modify file characteristics:
61 Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
65 There are no restrictions on this code, you may sell it, include it
66 with any commercial package, or feed it to a whale.. However, I would
67 appreciate it if you kept this comment in the source code so that anyone
68 receiving this code knows who to contact in case of problems. Note that
69 I do not demand this condition..
71 ---------------------------------------------------------------------------*/
76 /*****************************/
77 /* Includes, Defines, etc. */
78 /*****************************/
86 #include <atrdef.h> /* this gets created with the c3.0 compiler */
87 #include <fibdef.h> /* this gets created with the c3.0 compiler */
89 #include "VMSmunch.h" /* GET/SET_TIMES, RTYPE, etc. */
90 #include "VMSmunch_private.h" /* fatdef.h, etc. */
92 #define RTYPE fat$r_rtype_overlay.fat$r_rtype_bits
93 #define RATTRIB fat$r_rattrib_overlay.fat$r_rattrib_bits
100 # define SS$_NORMAL 1
101 # define SS$_BADPARAM 20
108 /*************************/
109 /* Function VMSmunch() */
110 /*************************/
112 int VMSmunch( filename, action, ptr )
113 char *filename, *ptr;
117 /* original file.c variables */
119 static struct FAB Fab;
120 static struct NAM Nam;
121 static struct fibdef Fib; /* short fib */
123 static struct dsc$descriptor FibDesc =
124 {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib};
125 static struct dsc$descriptor_s DevDesc =
126 {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
127 static struct fatdef Fat;
132 static struct fjndef jnl;
133 static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
134 static short int revisions;
135 static unsigned long uic;
137 unsigned short int value;
146 static struct atrdef Atr[] = {
147 {ATR$S_RECATTR,ATR$C_RECATTR,&Fat}, /* record attributes */
148 {ATR$S_UCHAR,ATR$C_UCHAR,&uchar}, /* File characteristics */
149 {ATR$S_CREDATE,ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
150 {ATR$S_REVDATE,ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
151 {ATR$S_EXPDATE,ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */
152 {ATR$S_BAKDATE,ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */
153 {ATR$S_ASCDATES,ATR$C_ASCDATES,&revisions}, /* number of revisions */
154 {ATR$S_FPRO,ATR$C_FPRO,&prot}, /* file protection */
155 {ATR$S_UIC,ATR$C_UIC,&uic}, /* file owner */
156 {ATR$S_JOURNAL,ATR$C_JOURNAL,&jnl}, /* journal flags */
160 static char EName[NAM$C_MAXRSS];
161 static char RName[NAM$C_MAXRSS];
162 static struct dsc$descriptor_s FileName =
163 {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
164 static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
165 static short int DevChan;
166 static short int iosb[4];
168 static long int i,status;
169 /* static char *retval; */
172 /* new VMSmunch variables */
174 static int old_rtype=FAT$C_FIXED; /* storage for record type */
178 /*---------------------------------------------------------------------------
179 Initialize attribute blocks, parse filename, resolve any wildcards, and
181 ---------------------------------------------------------------------------*/
183 /* initialize RMS structures, we need a NAM to retrieve the FID */
185 Fab.fab$l_fna = filename;
186 Fab.fab$b_fns = strlen(filename);
187 Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
189 Nam.nam$l_esa = EName; /* expanded filename */
190 Nam.nam$b_ess = sizeof(EName);
191 Nam.nam$l_rsa = RName; /* resultant filename */
192 Nam.nam$b_rss = sizeof(RName);
194 /* do $PARSE and $SEARCH here */
195 status = sys$parse(&Fab);
196 if (!(status & 1)) return(status);
198 /* search for the first file.. If none signal error */
199 status = sys$search(&Fab);
200 if (!(status & 1)) return(status);
203 /* initialize Device name length, note that this points into the NAM
204 to get the device name filled in by the $PARSE, $SEARCH services */
205 DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
207 status = sys$assign(&DevDesc,&DevChan,0,0);
208 if (!(status & 1)) return(status);
210 FileName.dsc$a_pointer = Nam.nam$l_name;
211 FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
213 /* Initialize the FIB */
216 Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
218 Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
222 Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
224 Fib.fib$w_did[i]=Nam.nam$w_did[i];
227 /* Use the IO$_ACCESS function to return info about the file */
228 /* Note, used this way, the file is not opened, and the expiration */
229 /* and revision dates are not modified */
230 status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
231 &FibDesc,&FileName,0,0,&Atr,0);
244 /*-----------------------------------------------------------------------
245 We have the current information from the file: now see what user
247 -----------------------------------------------------------------------*/
252 asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
253 asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
257 bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
258 bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
261 case GET_RTYPE: /* non-modifying */
262 *(int *)ptr = Fat.RTYPE.fat$v_rtype;
263 return RMS$_NORMAL; /* return to user */
267 old_rtype = Fat.RTYPE.fat$v_rtype; /* save current one */
268 if ((*(int *)ptr < FAT$C_UNDEFINED) ||
269 (*(int *)ptr > FAT$C_STREAMCR))
270 Fat.RTYPE.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */
272 Fat.RTYPE.fat$v_rtype = *(int *)ptr;
276 Fat.RTYPE.fat$v_rtype = old_rtype;
280 return SS$_BADPARAM; /* anything better? */
283 /*-----------------------------------------------------------------------
284 Go back and write modified data to the file header.
285 -----------------------------------------------------------------------*/
287 /* note, part of the FIB was cleared by earlier QIOW, so reset it */
289 Fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD;
291 Fib.fib$l_acctl = FIB$M_NORECORD;
295 Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
297 Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
301 Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
303 Fib.fib$w_did[i]=Nam.nam$w_did[i];
306 /* Use the IO$_MODIFY function to change info about the file */
307 /* Note, used this way, the file is not opened, however this would */
308 /* normally cause the expiration and revision dates to be modified. */
309 /* Using FIB$M_NORECORD prohibits this from happening. */
310 status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
311 &FibDesc,&FileName,0,0,&Atr,0);
325 status = sys$dassgn(DevChan);
326 if (!(status & 1)) return(status);
328 /* look for next file, if none, no big deal.. */
329 status = sys$search(&Fab);
331 } /* end function VMSmunch() */
337 /***********************/
338 /* Function bintim() */
339 /***********************/
341 void asctim(time,binval) /* convert 64-bit binval to string, put in time */
345 static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
346 /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
348 date_str.dsc$a_pointer = time;
349 sys$asctim(0, &date_str, binval, 0);
357 /***********************/
358 /* Function bintim() */
359 /***********************/
361 void bintim(time,binval) /* convert time string to 64 bits, put in binval */
365 static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
367 date_str.dsc$w_length = strlen(time);
368 date_str.dsc$a_pointer = time;
369 sys$bintim(&date_str, binval);