home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip21.zip / vms / vms.c < prev    next >
C/C++ Source or Header  |  1996-04-01  |  5KB  |  150 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  * VMS portions copyright (C) 1993 Igor Mandrichenko.                    *
  4.  * Permission is granted to any individual or institution to use, copy,  *
  5.  * or redistribute this software so long as all of the original files    *
  6.  * are included, that it is not sold for profit, and that this copyright *
  7.  * notice is retained.                                                   *
  8.  *                                                                       *
  9.  *************************************************************************/
  10.  
  11. /*
  12.  *  vms.c (zip) by Igor Mandrichenko    Version 2.2-2
  13.  *
  14.  *  Revision history:
  15.  *  ...
  16.  *  2.2-2       18-jan-1993     I.Mandrichenko
  17.  *      vms_stat() added - version of stat() that handles special
  18.  *      case when end-of-file-block == 0
  19.  */
  20.  
  21. #ifdef VMS                      /* For VMS only ! */
  22.  
  23. #include "zip.h"
  24.  
  25. #ifndef __STARLET_LOADED
  26. #include <starlet.h>
  27. #endif
  28. #if !defined(_RMS_H) && !defined(__RMS_LOADED)
  29. #include <rms.h>
  30. #endif
  31.  
  32. #ifndef UTIL
  33.  
  34. /* Include the `VMS attributes' preserving file-io code. We distinguish
  35.    between two incompatible flavours of storing VMS attributes in the
  36.    Zip archive:
  37.    a) The "PKware" style follows the extra field specification for
  38.       PKware's VMS Zip.
  39.    b) The "IM (Info-ZIP)" flavour was defined from scratch by
  40.       Igor Mandrichenko. This version has be used in official Info-ZIP
  41.       releases for several years and is known to work well.
  42.  */
  43.  
  44. #if defined(VMS_PK_EXTRA)
  45. #include "vms_pk.c"
  46. #else
  47. #include "vms_im.c"
  48. #endif
  49.  
  50. #endif /* !UTIL */
  51.  
  52. #ifndef ERR
  53. #define ERR(x) (((x)&1)==0)
  54. #endif
  55.  
  56. #ifndef NULL
  57. #define NULL (void*)(0L)
  58. #endif
  59.  
  60. int vms_stat(file,s)
  61. char *file;
  62. stat_t *s;
  63. {
  64.     int status;
  65.     int staterr;
  66.     struct FAB fab;
  67.     struct XABFHC fhc;
  68.  
  69.     /*
  70.      *  In simplest case when stat() returns "ok" and file size is
  71.      *  nonzero or this is directory, finish with this
  72.      */
  73.  
  74.     if( (staterr=stat(file,s)) == 0
  75.         && ( (int)(s->st_size) >= 0               /* Size - ok */
  76.              || (s->st_mode & S_IFREG) == 0       /* Not a plain file */
  77.            )
  78.     ) return staterr;
  79.  
  80.     /*
  81.      *  Get here to handle the special case when stat() returns
  82.      *  invalid file size. Use RMS to compute the size.
  83.      *  When EOF block is zero, set file size to its physical size.
  84.      *  One more case to get here is when this is remote file accessed
  85.      *  via DECnet.
  86.      */
  87.  
  88.     fab = cc$rms_fab;
  89.     fhc = cc$rms_xabfhc;
  90.     fab.fab$l_fna = file;
  91.     fab.fab$b_fns = strlen(file);
  92.     fab.fab$l_xab = (char*)(&fhc);
  93.  
  94.     fab.fab$b_fac = FAB$M_GET;
  95.  
  96.     status = sys$open(&fab);
  97.     fab.fab$l_xab = (char*)0L;
  98.     sys$close(&fab);
  99.  
  100.     if( !ERR(status) )
  101.     {
  102.         if( fhc.xab$l_ebk > 0 )
  103.             s->st_size = ( fhc.xab$l_ebk-1 ) * 512 + fhc.xab$w_ffb;
  104.         else if( fab.fab$b_org == FAB$C_IDX
  105.                  || fab.fab$b_org == FAB$C_REL
  106.                  || fab.fab$b_org == FAB$C_HSH )
  107.                 /* Special case, when ebk=0: save entire allocated space */
  108.                     s->st_size = fhc.xab$l_hbk * 512;
  109.         else
  110.             s->st_size = fhc.xab$w_ffb;
  111.         return 0; /* stat() success code */
  112.     }
  113.     else
  114.         return status;
  115. }
  116.  
  117. void vms_exit(e)
  118.    int e;
  119. {
  120. /*---------------------------------------------------------------------------
  121.     Return an intelligent status/severity level if RETURN_SEVERITY defined:
  122.  
  123.     $STATUS          $SEVERITY = $STATUS & 7
  124.     31 .. 16 15 .. 3   2 1 0
  125.                        -----
  126.     VMS                0 0 0  0    Warning
  127.     FACILITY           0 0 1  1    Success
  128.     Number             0 1 0  2    Error
  129.              MESSAGE   0 1 1  3    Information
  130.              Number    1 0 0  4    Severe (fatal) error
  131.  
  132.     0x7FFF0000 was chosen (by experimentation) to be outside the range of
  133.     VMS FACILITYs that have dedicated message numbers.  Hopefully this will
  134.     always result in silent exits--it does on VMS 5.4.  Note that the C li-
  135.     brary translates exit arguments of zero to a $STATUS value of 1 (i.e.,
  136.     exit is both silent and has a $SEVERITY of "success").
  137.   ---------------------------------------------------------------------------*/
  138.   {
  139.     int severity = (e == 2 || (e >= 9 && e <= 11))? 2 : 4;
  140.  
  141.     exit(                                     /* $SEVERITY:        */
  142.          (e == ZE_OK) ? 1 :                   /*   success         */
  143.          (e == 1) ? 0x7FFF0000 :              /*   warning         */
  144.          (0x7FFF0000 | (e << 4) | severity)   /*   error or fatal  */
  145.         );
  146.    }
  147. }
  148.  
  149. #endif /* VMS */
  150.