1/* 2 Copyright (c) 1990-2007 Info-ZIP. All rights reserved. 3 4 See the accompanying file LICENSE, version 2007-Mar-4 or later 5 (the contents of which are also included in zip.h) for terms of use. 6 If, for some reason, all these files are missing, the Info-ZIP license 7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 8*/ 9 10/* 2004-12-13 SMS. 11 * Disabled the module name macro to accommodate old GNU C which didn't 12 * obey the directive, and thus confused MMS/MMK where the object 13 * library dependencies need to have the correct module name. 14 */ 15#if 0 16# define module_name VMSMUNCH 17# define module_version "V1.3-4" 18#endif /* 0 */ 19 20/* 21 * Modified by: 22 * 23 * v1.3.1 O.v.d.Linden, C. Spieler 04-JUL-1998 14:35 24 * Modified check that decides on the type of definitions for 25 * FIB$W_FID etc. to support GNU C. 26 * 27 * v1.3 Hunter Goatley 14-SEP-1992 08:51 28 * Added definitions of FIB$W_FID, FIB$W_DID, and 29 * FIB$L_ACCTL to allow for the fact that fibdef 30 * contains variant_unions under Alpha. 31 */ 32/*--------------------------------------------------------------------------- 33 34 vmsmunch.c version 1.2 28 Apr 1992 35 36 This routine is a blatant and unrepentent appropriation of all the nasty 37 and difficult-to-do and complicated VMS shenanigans which Joe Meadows has 38 so magnificently captured in his FILE utility. Not only that, it's even 39 allowed! (see below). But let it be clear at the outset that Joe did all 40 the work; yea, verily, he is truly a godlike unit. 41 42 The appropriations and modifications herein were performed primarily by 43 him known as "Cave Newt," although the Info-ZIP working group probably had 44 their fingers in it somewhere along the line. The idea is to put the raw 45 power of Joe's original routine at the disposal of various routines used 46 by UnZip (and Zip, possibly), not least among them the utime() function. 47 Read on for details... 48 49 01-SEP-1994 Richard Levitte <levitte@e.kth.se> 50 If one of the fields given to VMSmunch are NULL, 51 do not update the corresponding daytime. 52 53 18-JUL-1994 Hunter Goatley <goathunter@WKU.EDU> 54 Fixed IO$_ACCESS call. 55 56 18-Jul-1994 Richard Levitte levitte@e.kth.se 57 Changed VMSmunch() to deassign the channel before 58 returning when an error has occured. 59 60 02-Apr-1994 Jamie Hanrahan jeh@cmkrnl.com 61 Moved definition of VMStimbuf struct from here 62 to vmsmunch.h 63 --------------------------------------------------------------------------- 64 65 Usage (i.e., "interface," in geek-speak): 66 67 int VMSmunch( char *filename, int action, char *ptr ); 68 69 filename the name of the file on which to be operated, obviously 70 action an integer which specifies what action to take 71 ptr pointer to any extra item which may be needed (else NULL) 72 73 The possible values for the action argument are as follows: 74 75 GET_TIMES get the creation and revision dates of filename; ptr 76 must point to an empty VMStimbuf struct, as defined 77 in vmsmunch.h 78 (with room for at least 24 characters, including term.) 79 SET_TIMES set the creation and revision dates of filename (utime 80 option); ptr must point to a valid VMStimbuf struct, 81 as defined in vmsmunch.h 82 GET_RTYPE get the record type of filename; ptr must point to an 83 integer which, on return, is set to the type (as defined 84 in vmsdefs.h: FAT$C_* defines) 85 CHANGE_RTYPE change the record type to that specified by the integer 86 to which ptr points; save the old record type (later 87 saves overwrite earlier ones) 88 RESTORE_RTYPE restore the record type to the previously saved value; 89 or, if none, set it to "fixed-length, 512-byte" record 90 format (ptr not used) 91 92 --------------------------------------------------------------------------- 93 94 Comments from FILE.C, a utility to modify file characteristics: 95 96 Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center 97 BITNET: JOE@FHCRCVAX 98 PHONE: (206) 467-4970 99 100 There are no restrictions on this code, you may sell it, include it 101 with any commercial package, or feed it to a whale.. However, I would 102 appreciate it if you kept this comment in the source code so that anyone 103 receiving this code knows who to contact in case of problems. Note that 104 I do not demand this condition.. 105 106 ---------------------------------------------------------------------------*/ 107 108 109/* 2004-12-13 SMS. 110 * Disabled the module name macro to accommodate old GNU C which didn't 111 * obey the directive, and thus confused MMS/MMK where the object 112 * library dependencies need to have the correct module name. 113 */ 114#if 0 115# if defined(__DECC) || defined(__GNUC__) 116# pragma module module_name module_version 117# else 118# module module_name module_version 119# endif 120#endif /* 0 */ 121 122/*****************************/ 123/* Includes, Defines, etc. */ 124/*****************************/ 125 126/* Accomodation for /NAMES = AS_IS with old header files. */ 127 128#define sys$asctim SYS$ASCTIM 129#define sys$assign SYS$ASSIGN 130#define sys$bintim SYS$BINTIM 131#define sys$dassgn SYS$DASSGN 132#define sys$parse SYS$PARSE 133#define sys$qiow SYS$QIOW 134#define sys$search SYS$SEARCH 135 136#include "zip.h" 137 138#include <stdio.h> 139#include <string.h> 140#include <iodef.h> 141#include <starlet.h> 142#include <fibdef.h> /* this gets created with the c3.0 compiler */ 143 144/* 145 * Under Alpha (DEC C in VAXC mode) and under `good old' VAXC, the FIB unions 146 * are declared as variant_unions. DEC C (Alpha) in ANSI modes and third 147 * party compilers which do not support `variant_union' define preprocessor 148 * symbols to `hide' the "intermediate union/struct" names from the 149 * programmer's API. 150 * We check the presence of these defines and for DEC's FIBDEF.H defining 151 * __union as variant_union to make sure we access the structure correctly. 152 */ 153#if defined(fib$w_did) || (defined(__union) && (__union == variant_union)) 154# define FIB$W_DID fib$w_did 155# define FIB$W_FID fib$w_fid 156# define FIB$L_ACCTL fib$l_acctl 157#else 158# define FIB$W_DID fib$r_did_overlay.fib$w_did 159# define FIB$W_FID fib$r_fid_overlay.fib$w_fid 160# define FIB$L_ACCTL fib$r_acctl_overlay.fib$l_acctl 161#endif 162 163#include "vms.h" 164#include "vmsmunch.h" /* GET/SET_TIMES, RTYPE, etc. */ 165#include "vmsdefs.h" /* fatdef.h, etc. */ 166 167static void asctim(char *time, long int binval[2]); 168static void bintim(char *time, long int binval[2]); 169 170/* from <ssdef.h> */ 171#ifndef SS$_NORMAL 172# define SS$_NORMAL 1 173# define SS$_BADPARAM 20 174#endif 175 176 177/* On VAX, define Goofy VAX Type-Cast to obviate /standard = vaxc. 178 Otherwise, lame system headers on VAX cause compiler warnings. 179 (GNU C may define vax but not __VAX.) 180*/ 181#ifdef vax 182# define __VAX 1 183#endif /* def vax */ 184 185#ifdef __VAX 186# define GVTC (unsigned int) 187#else /* def __VAX */ 188# define GVTC 189#endif /* def __VAX */ 190 191 192/*************************/ 193/* Function VMSmunch() */ 194/*************************/ 195 196int VMSmunch( 197 char *filename, 198 int action, 199 char *ptr ) 200{ 201 202 /* original file.c variables */ 203 204 static struct FAB Fab; 205 static struct NAM_STRUCT Nam; 206 static struct fibdef Fib; /* short fib */ 207 208 static struct dsc$descriptor FibDesc = 209 {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib}; 210 static struct dsc$descriptor_s DevDesc = 211 {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.NAM_DVI[1]}; 212 static struct fatdef Fat; 213 static union { 214 struct fchdef fch; 215 long int dummy; 216 } uchar; 217 static struct fjndef jnl; 218 static long int Cdate[2],Rdate[2],Edate[2],Bdate[2]; 219 static short int revisions; 220 static unsigned long uic; 221#if defined(__DECC) || defined(__DECCXX) 222#pragma __member_alignment __save 223#pragma __nomember_alignment 224#endif /* __DECC || __DECCXX */ 225 static union { 226 unsigned short int value; 227 struct { 228 unsigned system : 4; 229 unsigned owner : 4; 230 unsigned group : 4; 231 unsigned world : 4; 232 } bits; 233 } prot; 234#if defined(__DECC) || defined(__DECCXX) 235#pragma __member_alignment __restore 236#endif /* __DECC || __DECCXX */ 237 238 static struct atrdef Atr[] = { 239 {sizeof(Fat),ATR$C_RECATTR, GVTC &Fat}, /* record attributes */ 240 {sizeof(uchar),ATR$C_UCHAR, GVTC &uchar}, /* File characteristics */ 241 {sizeof(Cdate),ATR$C_CREDATE, GVTC &Cdate[0]}, /* Creation date */ 242 {sizeof(Rdate),ATR$C_REVDATE, GVTC &Rdate[0]}, /* Revision date */ 243 {sizeof(Edate),ATR$C_EXPDATE, GVTC &Edate[0]}, /* Expiration date */ 244 {sizeof(Bdate),ATR$C_BAKDATE, GVTC &Bdate[0]}, /* Backup date */ 245 {sizeof(revisions),ATR$C_ASCDATES, GVTC &revisions}, /* number of revs */ 246 {sizeof(prot),ATR$C_FPRO, GVTC &prot}, /* file protection */ 247 {sizeof(uic),ATR$C_UIC, GVTC &uic}, /* file owner */ 248 {sizeof(jnl),ATR$C_JOURNAL, GVTC &jnl}, /* journal flags */ 249 {0,0,0} 250 } ; 251 252 static char EName[NAM_MAXRSS]; 253 static char RName[NAM_MAXRSS]; 254 static struct dsc$descriptor_s FileName = 255 {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; 256 static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; 257 static short int DevChan; 258 static short int iosb[4]; 259 260 static long int i,status; 261/* static char *retval; */ 262 263 264 /* new VMSmunch variables */ 265 266 static int old_rtype=FAT$C_FIXED; /* storage for record type */ 267 268 269 270/*--------------------------------------------------------------------------- 271 Initialize attribute blocks, parse filename, resolve any wildcards, and 272 get the file info. 273 ---------------------------------------------------------------------------*/ 274 275 /* Initialize RMS structures. We need a NAM[L] to retrieve the FID. */ 276 Fab = cc$rms_fab; 277 Fab.fab$l_fna = filename; 278 Fab.fab$b_fns = strlen(filename); 279 Fab.FAB_NAM = &Nam; /* FAB has an associated NAM[L]. */ 280 Nam = CC_RMS_NAM; 281 Nam.NAM_ESA = EName; /* expanded filename */ 282 Nam.NAM_ESS = sizeof(EName); 283 Nam.NAM_RSA = RName; /* resultant filename */ 284 Nam.NAM_RSS = sizeof(RName); 285 286 /* do $PARSE and $SEARCH here */ 287 status = sys$parse(&Fab); 288 if (!(status & 1)) return(status); 289 290 /* search for the first file.. If none signal error */ 291 status = sys$search(&Fab); 292 if (!(status & 1)) return(status); 293 294 while (status & 1) { 295 /* initialize Device name length, note that this points into the NAM[L] 296 to get the device name filled in by the $PARSE, $SEARCH services */ 297 DevDesc.dsc$w_length = Nam.NAM_DVI[0]; 298 299 status = sys$assign(&DevDesc,&DevChan,0,0); 300 if (!(status & 1)) return(status); 301 302 FileName.dsc$a_pointer = Nam.NAM_L_NAME; 303 FileName.dsc$w_length = Nam.NAM_B_NAME+Nam.NAM_B_TYPE+Nam.NAM_B_VER; 304 305 /* Initialize the FIB */ 306 for (i=0;i<3;i++) { 307 Fib.FIB$W_FID[i]=Nam.NAM_FID[i]; 308 Fib.FIB$W_DID[i]=Nam.NAM_DID[i]; 309 } 310 311 /* Use the IO$_ACCESS function to return info about the file */ 312 /* Note, used this way, the file is not opened, and the expiration */ 313 /* and revision dates are not modified */ 314 status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0, 315 &FibDesc,&FileName,0,0,&Atr,0); 316 if (!(status & 1) || !((status = iosb[0]) & 1)) { 317 sys$dassgn(DevChan); 318 return(status); 319 } 320 321 /*----------------------------------------------------------------------- 322 We have the current information from the file: now see what user 323 wants done with it. 324 -----------------------------------------------------------------------*/ 325 326 switch (action) { 327 328 case GET_TIMES: /* non-modifying */ 329 asctim(((struct VMStimbuf *)ptr)->modtime, Cdate); 330 asctim(((struct VMStimbuf *)ptr)->actime, Rdate); 331 sys$dassgn(DevChan); 332 return RMS$_NORMAL; /* return to user */ 333 break; 334 335 case SET_TIMES: 336 if (((struct VMStimbuf *)ptr)->modtime != (char *)NULL) 337 bintim(((struct VMStimbuf *)ptr)->modtime, Cdate); 338 if (((struct VMStimbuf *)ptr)->actime != (char *)NULL) 339 bintim(((struct VMStimbuf *)ptr)->actime, Rdate); 340 break; 341 342 case GET_RTYPE: /* non-modifying */ 343 *(int *)ptr = Fat.fat$v_rtype; 344 sys$dassgn(DevChan); 345 return RMS$_NORMAL; /* return to user */ 346 break; 347 348 case CHANGE_RTYPE: 349 old_rtype = Fat.fat$v_rtype; /* save current one */ 350 if ((*(int *)ptr < FAT$C_UNDEFINED) || 351 (*(int *)ptr > FAT$C_STREAMCR)) 352 Fat.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */ 353 else 354 Fat.fat$v_rtype = *(int *)ptr; 355 break; 356 357 case RESTORE_RTYPE: 358 Fat.fat$v_rtype = old_rtype; 359 break; 360 361 default: 362 sys$dassgn(DevChan); 363 return SS$_BADPARAM; /* anything better? */ 364 } 365 366 /*----------------------------------------------------------------------- 367 Go back and write modified data to the file header. 368 -----------------------------------------------------------------------*/ 369 370 /* note, part of the FIB was cleared by earlier QIOW, so reset it */ 371 Fib.FIB$L_ACCTL = FIB$M_NORECORD; 372 for (i=0;i<3;i++) { 373 Fib.FIB$W_FID[i]=Nam.NAM_FID[i]; 374 Fib.FIB$W_DID[i]=Nam.NAM_DID[i]; 375 } 376 377 /* Use the IO$_MODIFY function to change info about the file */ 378 /* Note, used this way, the file is not opened, however this would */ 379 /* normally cause the expiration and revision dates to be modified. */ 380 /* Using FIB$M_NORECORD prohibits this from happening. */ 381 status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0, 382 &FibDesc,&FileName,0,0,&Atr,0); 383 if (!(status & 1) || !((status = iosb[0]) & 1)) { 384 sys$dassgn(DevChan); 385 return(status); 386 } 387 388 status = sys$dassgn(DevChan); 389 if (!(status & 1)) return(status); 390 391 /* look for next file, if none, no big deal.. */ 392 status = sys$search(&Fab); 393 } 394 return(status); 395} /* end function VMSmunch() */ 396 397 398 399 400 401/***********************/ 402/* Function asctim() */ 403/***********************/ 404 405static void asctim( /* convert 64-bit binval to string, put in time */ 406 char *time, 407 long int binval[2] ) 408{ 409 static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; 410 /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */ 411 412 date_str.dsc$a_pointer = time; 413 sys$asctim(0, &date_str, binval, 0); 414 time[23] = '\0'; 415} 416 417 418 419 420 421/***********************/ 422/* Function bintim() */ 423/***********************/ 424 425static void bintim( /* convert time string to 64 bits, put in binval */ 426 char *time, 427 long int binval[2] ) 428{ 429 static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; 430 431 date_str.dsc$w_length = strlen(time); 432 date_str.dsc$a_pointer = time; 433 sys$bintim(&date_str, binval); 434} 435