home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip22.zip / vms / vmsmunch.c < prev    next >
C/C++ Source or Header  |  1996-12-14  |  13KB  |  357 lines

  1. /*
  2.  *  Modified by:
  3.  *
  4.  *    v1.3            Hunter Goatley          14-SEP-1992 08:51
  5.  *            Added definitions of FIB$W_FID, FIB$W_DID, and
  6.  *            FIB$L_ACCTL to allow for the fact that fibdef
  7.  *            contains variant_unions under Alpha.
  8.  */
  9. /*---------------------------------------------------------------------------
  10.  
  11.   vmsmunch.c                    version 1.2                     28 Apr 1992
  12.  
  13.   This routine is a blatant and unrepentent appropriation of all the nasty
  14.   and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
  15.   so magnificently captured in his FILE utility.  Not only that, it's even
  16.   allowed! (see below).  But let it be clear at the outset that Joe did all
  17.   the work; yea, verily, he is truly a godlike unit.
  18.  
  19.   The appropriations and modifications herein were performed primarily by
  20.   him known as "Cave Newt," although the Info-ZIP working group probably had
  21.   their fingers in it somewhere along the line.  The idea is to put the raw
  22.   power of Joe's original routine at the disposal of various routines used
  23.   by UnZip (and Zip, possibly), not least among them the utime() function.
  24.   Read on for details...
  25.  
  26.         02-Apr-1994     Jamie Hanrahan  jeh@cmkrnl.com
  27.                         Moved definition of VMStimbuf struct from here
  28.                         to vmsmunch.h
  29.   ---------------------------------------------------------------------------
  30.  
  31.   Usage (i.e., "interface," in geek-speak):
  32.  
  33.      int VMSmunch( char *filename, int action, char *ptr );
  34.  
  35.      filename   the name of the file on which to be operated, obviously
  36.      action     an integer which specifies what action to take
  37.      ptr        pointer to any extra item which may be needed (else NULL)
  38.  
  39.   The possible values for the action argument are as follows:
  40.  
  41.      GET_TIMES      get the creation and revision dates of filename; ptr
  42.                     must point to an empty VMStimbuf struct, as defined
  43.                     in vmsmunch.h
  44.                     (with room for at least 24 characters, including term.)
  45.      SET_TIMES      set the creation and revision dates of filename (utime
  46.                     option); ptr must point to a valid VMStimbuf struct,
  47.                     as defined in vmsmunch.h
  48.      GET_RTYPE      get the record type of filename; ptr must point to an
  49.                     integer which, on return, is set to the type (as defined
  50.                     in vmsdefs.h:  FAT$C_* defines)
  51.      CHANGE_RTYPE   change the record type to that specified by the integer
  52.                     to which ptr points; save the old record type (later
  53.                     saves overwrite earlier ones)
  54.      RESTORE_RTYPE  restore the record type to the previously saved value;
  55.                     or, if none, set it to "fixed-length, 512-byte" record
  56.                     format (ptr not used)
  57.  
  58.   ---------------------------------------------------------------------------
  59.  
  60.   Comments from FILE.C, a utility to modify file characteristics:
  61.  
  62.      Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
  63.      BITNET: JOE@FHCRCVAX
  64.      PHONE: (206) 467-4970
  65.  
  66.      There are no restrictions on this code, you may sell it, include it
  67.      with any commercial package, or feed it to a whale.. However, I would
  68.      appreciate it if you kept this comment in the source code so that anyone
  69.      receiving this code knows who to contact in case of problems. Note that
  70.      I do not demand this condition..
  71.  
  72.   ---------------------------------------------------------------------------*/
  73.  
  74.  
  75.  
  76.  
  77. /*****************************/
  78. /*  Includes, Defines, etc.  */
  79. /*****************************/
  80.  
  81. #include <descrip.h>
  82. #include <rms.h>
  83. #include <stdio.h>
  84. #include <iodef.h>
  85. #include <string.h>
  86. #include <starlet.h>
  87. #include <atrdef.h>   /* this gets created with the c3.0 compiler */
  88. #include <fibdef.h>   /* this gets created with the c3.0 compiler */
  89.  
  90. /*
  91.  *  Under Alpha, the FIB unions are declared as variant_unions.
  92.  *  FIBDEF.H includes the definition of __union, which we check
  93.  *  below to make sure we access the structure correctly.
  94.  */
  95. #if defined(__union) && (__union == variant_union)
  96. #define FIB$W_FID     fib$w_fid
  97. #define FIB$W_DID     fib$w_did
  98. #define FIB$L_ACCTL   fib$l_acctl
  99. #else
  100. #define FIB$W_FID     fib$r_fid_overlay.fib$w_fid
  101. #define FIB$W_DID     fib$r_did_overlay.fib$w_did
  102. #define FIB$L_ACCTL   fib$r_acctl_overlay.fib$l_acctl
  103. #endif /* #if (defined(__union) && (__union == variant_union)) */
  104.  
  105. #include "vmsmunch.h"  /* GET/SET_TIMES, RTYPE, etc. */
  106. #include "vmsdefs.h"   /* fatdef.h, etc. */
  107.  
  108. static void asctim(char *time, long int binval[2]);
  109. static void bintim(char *time, long int binval[2]);
  110.  
  111. /* from <ssdef.h> */
  112. #ifndef SS$_NORMAL
  113. #  define SS$_NORMAL    1
  114. #  define SS$_BADPARAM  20
  115. #endif
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /*************************/
  122. /*  Function VMSmunch()  */
  123. /*************************/
  124.  
  125. int VMSmunch(
  126.     char  *filename,
  127.     int   action,
  128.     char  *ptr )
  129. {
  130.  
  131.     /* original file.c variables */
  132.  
  133.     static struct FAB Fab;
  134.     static struct NAM Nam;
  135.     static struct fibdef Fib; /* short fib */
  136.  
  137.     static struct dsc$descriptor FibDesc =
  138.       {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib};
  139.     static struct dsc$descriptor_s DevDesc =
  140.       {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
  141.     static struct fatdef Fat;
  142.     static union {
  143.       struct fchdef fch;
  144.       long int dummy;
  145.     } uchar;
  146.     static struct fjndef jnl;
  147.     static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
  148.     static short int revisions;
  149.     static unsigned long uic;
  150. #if defined(__DECC) || defined(__DECCXX)
  151. #pragma __member_alignment __save
  152. #pragma __nomember_alignment
  153. #endif /* __DECC || __DECCXX */
  154.     static union {
  155.       unsigned short int value;
  156.       struct {
  157.         unsigned system : 4;
  158.         unsigned owner : 4;
  159.         unsigned group : 4;
  160.         unsigned world : 4;
  161.       } bits;
  162.     } prot;
  163. #if defined(__DECC) || defined(__DECCXX)
  164. #pragma __member_alignment __restore
  165. #endif /* __DECC || __DECCXX */
  166.  
  167.     static struct atrdef Atr[] = {
  168.       {sizeof(Fat),ATR$C_RECATTR,&Fat},        /* record attributes */
  169.       {sizeof(uchar),ATR$C_UCHAR,&uchar},      /* File characteristics */
  170.       {sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
  171.       {sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
  172.       {sizeof(Edate),ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */
  173.       {sizeof(Bdate),ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */
  174.       {sizeof(revisions),ATR$C_ASCDATES,&revisions}, /* number of revisions */
  175.       {sizeof(prot),ATR$C_FPRO,&prot},         /* file protection  */
  176.       {sizeof(uic),ATR$C_UIC,&uic},            /* file owner */
  177.       {sizeof(jnl),ATR$C_JOURNAL,&jnl},        /* journal flags */
  178.       {0,0,0}
  179.     } ;
  180.  
  181.     static char EName[NAM$C_MAXRSS];
  182.     static char RName[NAM$C_MAXRSS];
  183.     static struct dsc$descriptor_s FileName =
  184.       {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  185.     static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  186.     static short int DevChan;
  187.     static short int iosb[4];
  188.  
  189.     static long int i,status;
  190. /*  static char *retval;  */
  191.  
  192.  
  193.     /* new VMSmunch variables */
  194.  
  195.     static int  old_rtype=FAT$C_FIXED;   /* storage for record type */
  196.  
  197.  
  198.  
  199. /*---------------------------------------------------------------------------
  200.     Initialize attribute blocks, parse filename, resolve any wildcards, and
  201.     get the file info.
  202.   ---------------------------------------------------------------------------*/
  203.  
  204.     /* initialize RMS structures, we need a NAM to retrieve the FID */
  205.     Fab = cc$rms_fab;
  206.     Fab.fab$l_fna = filename;
  207.     Fab.fab$b_fns = strlen(filename);
  208.     Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
  209.     Nam = cc$rms_nam;
  210.     Nam.nam$l_esa = EName; /* expanded filename */
  211.     Nam.nam$b_ess = sizeof(EName);
  212.     Nam.nam$l_rsa = RName; /* resultant filename */
  213.     Nam.nam$b_rss = sizeof(RName);
  214.  
  215.     /* do $PARSE and $SEARCH here */
  216.     status = sys$parse(&Fab);
  217.     if (!(status & 1)) return(status);
  218.  
  219.     /* search for the first file.. If none signal error */
  220.     status = sys$search(&Fab);
  221.     if (!(status & 1)) return(status);
  222.  
  223.     while (status & 1) {
  224.         /* initialize Device name length, note that this points into the NAM
  225.            to get the device name filled in by the $PARSE, $SEARCH services */
  226.         DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
  227.  
  228.         status = sys$assign(&DevDesc,&DevChan,0,0);
  229.         if (!(status & 1)) return(status);
  230.  
  231.         FileName.dsc$a_pointer = Nam.nam$l_name;
  232.         FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
  233.  
  234.         /* Initialize the FIB */
  235.         for (i=0;i<3;i++)
  236.             Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
  237.         for (i=0;i<3;i++)
  238.             Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
  239.  
  240.         /* Use the IO$_ACCESS function to return info about the file */
  241.         /* Note, used this way, the file is not opened, and the expiration */
  242.         /* and revision dates are not modified */
  243.         status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
  244.                           &FibDesc,&FileName,0,0,&Atr,0);
  245.         if (!(status & 1)) return(status);
  246.         status = iosb[0];
  247.         if (!(status & 1)) return(status);
  248.  
  249.     /*-----------------------------------------------------------------------
  250.         We have the current information from the file:  now see what user
  251.         wants done with it.
  252.       -----------------------------------------------------------------------*/
  253.  
  254.         switch (action) {
  255.  
  256.           case GET_TIMES:
  257.               asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  258.               asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
  259.               break;
  260.  
  261.           case SET_TIMES:
  262.               bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  263.               bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
  264.               break;
  265.  
  266.           case GET_RTYPE:   /* non-modifying */
  267.               *(int *)ptr = Fat.fat$v_rtype;
  268.               return RMS$_NORMAL;     /* return to user */
  269.               break;
  270.  
  271.           case CHANGE_RTYPE:
  272.               old_rtype = Fat.fat$v_rtype;              /* save current one */
  273.               if ((*(int *)ptr < FAT$C_UNDEFINED) ||
  274.                   (*(int *)ptr > FAT$C_STREAMCR))
  275.                   Fat.fat$v_rtype = FAT$C_STREAMLF;       /* Unix I/O happy */
  276.               else
  277.                   Fat.fat$v_rtype = *(int *)ptr;
  278.               break;
  279.  
  280.           case RESTORE_RTYPE:
  281.               Fat.fat$v_rtype = old_rtype;
  282.               break;
  283.  
  284.           default:
  285.               return SS$_BADPARAM;   /* anything better? */
  286.         }
  287.  
  288.     /*-----------------------------------------------------------------------
  289.         Go back and write modified data to the file header.
  290.       -----------------------------------------------------------------------*/
  291.  
  292.         /* note, part of the FIB was cleared by earlier QIOW, so reset it */
  293.         Fib.FIB$L_ACCTL = FIB$M_NORECORD;
  294.         for (i=0;i<3;i++)
  295.             Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
  296.         for (i=0;i<3;i++)
  297.             Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
  298.  
  299.         /* Use the IO$_MODIFY function to change info about the file */
  300.         /* Note, used this way, the file is not opened, however this would */
  301.         /* normally cause the expiration and revision dates to be modified. */
  302.         /* Using FIB$M_NORECORD prohibits this from happening. */
  303.         status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
  304.                           &FibDesc,&FileName,0,0,&Atr,0);
  305.         if (!(status & 1)) return(status);
  306.  
  307.         status = iosb[0];
  308.         if (!(status & 1)) return(status);
  309.  
  310.         status = sys$dassgn(DevChan);
  311.         if (!(status & 1)) return(status);
  312.  
  313.         /* look for next file, if none, no big deal.. */
  314.         status = sys$search(&Fab);
  315.     }
  316.     return(status);
  317. } /* end function VMSmunch() */
  318.  
  319.  
  320.  
  321.  
  322.  
  323. /***********************/
  324. /*  Function asctim()  */
  325. /***********************/
  326.  
  327. static void asctim(        /* convert 64-bit binval to string, put in time */
  328.     char *time,
  329.     long int binval[2] )
  330. {
  331.     static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  332.       /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
  333.  
  334.     date_str.dsc$a_pointer = time;
  335.     sys$asctim(0, &date_str, binval, 0);
  336.     time[23] = '\0';
  337. }
  338.  
  339.  
  340.  
  341.  
  342.  
  343. /***********************/
  344. /*  Function bintim()  */
  345. /***********************/
  346.  
  347. void bintim(               /* convert time string to 64 bits, put in binval */
  348.     char *time,
  349.     long int binval[2] )
  350. {
  351.     static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  352.  
  353.     date_str.dsc$w_length = strlen(time);
  354.     date_str.dsc$a_pointer = time;
  355.     sys$bintim(&date_str, binval);
  356. }
  357.