home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckvrtl.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  10KB  |  402 lines

  1. /*
  2.   C-Kermit C RTL replacement functions for VMS systems.
  3. */
  4.  
  5. /*----------------------------------------------------------------------
  6.  *
  7.  *       utime()
  8.  *
  9.  *    VMS C RTL before V7.3 lacks utime().  In V7.3, utime() sets only
  10.  *    the modified (revised) date, not the created date of a file.
  11.  *
  12.  *    UNIX "ls -l" reports the modified time.  VMS "DIRECTORY /DATE"
  13.  *    reports the creation time.  Reconciling these in FTP DIR reports
  14.  *    is non-trivial.
  15.  *
  16.  *    UNIX utime() sets revision and access times.  VMS does not always
  17.  *    maintain access times, so this utime() replacement sets the
  18.  *    creation and revision times to the specified revision (or
  19.  *    creation?) time.  Any access time is ignored.
  20.  *
  21.  *----------------------------------------------------------------------
  22.  */
  23.  
  24. #if __CRTL_VER >= 70300000
  25.  
  26. /* Avoid "%CC-W-EMPTYFILE, Source file does not contain any declarations." */
  27.  
  28. int dummy_function(void);
  29.  
  30. #else /* __CRTL_VER < 70300000 */
  31.  
  32. #include <errno.h>
  33. #include <string.h>
  34. #include <time.h>
  35. #include <unixlib.h>
  36.  
  37. #include <atrdef.h>
  38. #include <descrip.h>
  39. #include <fibdef.h>
  40. #include <iodef.h>
  41. #include <lib$routines.h>
  42. #include <rms.h>
  43. #include <starlet.h>
  44. #include <stsdef.h>
  45.  
  46. #include "ckvrtl.h"
  47. #include "ckvrms.h"
  48.  
  49. /* Use <iosbdef.h> if available.  Otherwise declare IOSB here. */
  50.  
  51. #if !defined( __VAX) && (__CRTL_VER >= 70000000)
  52. #include <iosbdef.h>
  53. #else /* __CRTL_VER >= 70000000 */
  54. typedef struct _iosb {
  55.         unsigned short int iosb$w_status; /* Final I/O status   */
  56.         unsigned short int iosb$w_bcnt; /* 16-bit byte count    */
  57.         unsigned int iosb$l_dev_depend; /* 32-bit dev dependent */
  58.     } IOSB;
  59. #endif /* !defined( __VAX) && (__CRTL_VER >= 70000000) */
  60.  
  61.  
  62. /* Ugly work-around for bad type in VAX <atrdef.h>. */
  63.  
  64. #ifdef __VAX
  65. #define UWA (unsigned int)
  66. #else /* def __VAX */
  67. #define UWA
  68. #endif /* def __VAX */
  69.  
  70. /*--------------------------------------------------------------------*/
  71.  
  72. #ifdef __DECC
  73.  
  74. /* Private utime() code. */
  75.  
  76. /* Action routine for decc$to_vms(), in utime(). */
  77.  
  78. char vms_path[ NAMX_C_MAXRSS+ 1];
  79.  
  80. int set_vms_name( char *name, int type)
  81. {
  82.    strncpy( vms_path, name, NAMX_C_MAXRSS);
  83.    vms_path[ NAMX_C_MAXRSS] = '\0';
  84.    return 1;
  85. }
  86.  
  87. #endif /* def __DECC */
  88.  
  89. /*--------------------------------------------------------------------*/
  90.  
  91. /* utime() replacement. */
  92.  
  93. int vms_utime( const char *path, const struct utimbuf *times)
  94. {
  95. time_t utc_unsigned;
  96.  
  97. int chan, i;
  98. int sts, sts2;
  99.  
  100. unsigned short int vms_num_vec_time[ 7];
  101. /* Static to avoid %CC-W-ADDRCONSTEXT from old (V4.0-000) DEC C. */
  102. static unsigned int vms_abs_time[ 2];
  103. struct tm *tms;
  104. struct _iosb iosb_q;
  105.  
  106. /* QIOW item list used to set creation and revision dates. */
  107.  
  108. struct atrdef ut_atr[ 3] = {
  109.  {sizeof( vms_abs_time), ATR$C_CREDATE, UWA vms_abs_time},
  110.  {sizeof( vms_abs_time), ATR$C_REVDATE, UWA vms_abs_time},
  111.  {0,0,0}};
  112.  
  113. /* Various RMS structures used for file access. */
  114.  
  115. struct FAB ut_fab = cc$rms_fab;
  116. struct RAB ut_rab = cc$rms_rab;
  117. struct NAMX ut_namx = CC_RMS_NAMX;
  118. static struct fibdef ut_fib;
  119.  
  120. /* Device and file name buffers and their descriptors. */
  121.  
  122. static char dev_namx[ NAMX_C_MAXRSS+ 1];
  123. char esa_namx[ NAMX_C_MAXRSS+ 1];
  124. char rsa_namx[ NAMX_C_MAXRSS+ 1];
  125.  
  126. struct dsc$descriptor dev_dsc =
  127.  {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, dev_namx};
  128.  
  129. struct dsc$descriptor fib_dsc =
  130.  {sizeof( ut_fib), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &ut_fib};
  131.  
  132. #ifdef __DECC
  133.  
  134. /* We will accept either a UNIX-like path name or a VMS-like path name. 
  135.    If a slash is found in the name, assume that it's UNIX-like, and
  136.    convert it to VMS form.  Otherwise, use it as-is.
  137. */
  138.  
  139. if (strchr( path, '/') != NULL)
  140.    {
  141.    sts = decc$to_vms( path, set_vms_name, 0, 0);
  142.    path = vms_path;
  143.    }
  144.  
  145. #endif /* def __DECC */
  146.  
  147. /* Install the VMS file specification into the FAB. */
  148.  
  149. ut_fab.fab$l_fna = (char *) path;
  150. ut_fab.fab$b_fns = (unsigned char) strlen( path);
  151.  
  152. ut_fab.fab$l_dna = "";
  153. ut_fab.fab$b_dns = 0;
  154.  
  155. /* Point the FAB to the NAMX. */
  156.  
  157. ut_fab.FAB_L_NAMX = &ut_namx;
  158.  
  159. /* Install the name buffers into the NAM. */
  160.  
  161. ut_namx.NAMX_L_ESA = esa_namx;
  162. ut_namx.NAMX_B_ESL = 0;
  163. ut_namx.NAMX_B_ESS = sizeof( esa_namx)- 1;
  164.  
  165. ut_namx.NAMX_L_RSA = rsa_namx;
  166. ut_namx.NAMX_B_RSL = 0;
  167. ut_namx.NAMX_B_RSS = sizeof( rsa_namx)- 1;
  168.  
  169. /* Convert the modification time (UTC time_t) to local "tm" time. */
  170.  
  171. tms = localtime( &(times-> modtime));
  172.  
  173. /* Move (translate) "tm" structure local time to VMS vector time. */
  174.  
  175. if (tms != NULL)
  176.    {
  177.    vms_num_vec_time[ 0] = tms-> tm_year+ 1900;
  178.    vms_num_vec_time[ 1] = tms-> tm_mon+ 1;
  179.    vms_num_vec_time[ 2] = tms-> tm_mday;
  180.    vms_num_vec_time[ 3] = tms-> tm_hour;
  181.    vms_num_vec_time[ 4] = tms-> tm_min;
  182.    vms_num_vec_time[ 5] = tms-> tm_sec;
  183.    vms_num_vec_time[ 6] = 0;  /* centiseconds */
  184.  
  185. /* Convert VMS vector time to VMS absolute time (quadword). */
  186.  
  187.    sts = lib$cvt_vectim( vms_num_vec_time, vms_abs_time);
  188.  
  189.    if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  190.       {
  191. /* Parse the file specification. */
  192.  
  193.       sts = sys$parse( &ut_fab, 0, 0);
  194.  
  195.       if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  196.          {
  197. /* Locate the file. (Gets the FID.) */
  198.  
  199.          sts = sys$search( &ut_fab, 0, 0);
  200.  
  201.          if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  202.             {
  203. /* Form the device name descriptor. */
  204.  
  205.             dev_dsc.dsc$w_length = ut_namx.NAMX_B_DEV;
  206.             dev_dsc.dsc$a_pointer = (char *) ut_namx.NAMX_L_DEV;
  207.  
  208. /* Assign a channel to the disk device. */
  209.  
  210.             sts = sys$assign( &dev_dsc, &chan, 0, 0);
  211.  
  212.             if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  213.                {
  214. /* Move the FID (and not the DID) into the FIB. */
  215.  
  216.                memset( (void *) &ut_fib, 0, sizeof( ut_fib));
  217.  
  218.                for (i = 0; i < 3; i++)
  219.                   {
  220.                   ut_fib.FIB_W_FID[ i] = ut_namx.NAMX_W_FID[ i];
  221.                   ut_fib.FIB_W_DID[ i] = 0;
  222.                   }
  223.  
  224. /* Prevent this QIOW from setting the revision time to now. */
  225.  
  226.                ut_fib.FIB_L_ACCTL = FIB$M_NORECORD;
  227.  
  228. /* Set the file dates. */
  229.  
  230.                sts = sys$qiow( 0,
  231.                                chan,
  232.                                IO$_MODIFY,
  233.                                &iosb_q,
  234.                                0,
  235.                                0,
  236.                                &fib_dsc,
  237.                                0,
  238.                                0,
  239.                                0,
  240.                                ut_atr,
  241.                                0);
  242.  
  243.                if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  244.                   {
  245.                    sts = iosb_q.iosb$w_status;
  246.                   }
  247.                sts2 = sys$dassgn( chan);
  248.  
  249.                if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  250.                   {
  251.                   sts = sts2;
  252.                   }
  253.                }
  254.             }
  255.          }
  256.       }
  257.    }
  258.  
  259. /* Convert successful VMS status to zero = success status.
  260.    If failure, set errno and vaxc$errno, and return -1 = failure status.
  261. */
  262.  
  263. if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  264.    {
  265.    sts = 0;
  266.    }
  267. else
  268.    {
  269.    errno = EVMSERR;
  270.    vaxc$errno = sts;
  271.    sts = -1;
  272.    }
  273.  
  274. return sts;
  275. }
  276.  
  277. #endif /* __CRTL_VER >= 70300000 [else] */
  278.  
  279. /**********************************************************************/
  280.  
  281. #if !defined( __VAX) && (__CRTL_VER >= 70301000)
  282.  
  283. #include <stdio.h>
  284. #include <unixlib.h>
  285.  
  286. /* Flag to sense if vms_init() was called.  (Handy for debug.) */
  287.  
  288. int vms_init_done = -1;
  289.  
  290.  
  291. /* vms_init()
  292.  
  293.       Uses LIB$INITIALIZE to set a collection of C RTL features without
  294.       requiring the user to define the corresponding logical names.
  295. */
  296.  
  297. /* Structure to hold a DECC$* feature name and its desired value. */
  298.  
  299. typedef struct
  300.    {
  301.    char *name;
  302.    int value;
  303.    } decc_feat_t;
  304.  
  305. /* Array of DECC$* feature names and their desired values. */
  306.  
  307. decc_feat_t decc_feat_array[] = {
  308.    /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
  309.  { "DECC$ARGV_PARSE_STYLE", 1 },
  310.    /* Preserve case for file names on ODS5 disks. */
  311.  { "DECC$EFS_CASE_PRESERVE", 1 },
  312.    /* Enable multiple dots (and most characters) in ODS5 file names,
  313.       while preserving VMS-ness of ";version". */
  314.  { "DECC$EFS_CHARSET", 1 },
  315.    /* List terminator. */
  316.  { (char *)NULL, 0 } };
  317.  
  318. /* LIB$INITIALIZE initialization function. */
  319.  
  320. static void vms_init( void)
  321. {
  322. int feat_index;
  323. int feat_value;
  324. int feat_value_max;
  325. int feat_value_min;
  326. int i;
  327. int sts;
  328.  
  329. /* Set the global flag to indicate that LIB$INITIALIZE worked. */
  330.  
  331. vms_init_done = 1;
  332.  
  333. /* Loop through all items in the decc_feat_array[]. */
  334.  
  335. for (i = 0; decc_feat_array[ i].name != NULL; i++)
  336.    {
  337.    /* Get the feature index. */
  338.    feat_index = decc$feature_get_index( decc_feat_array[ i].name);
  339.    if (feat_index >= 0)
  340.       {
  341.       /* Valid item.  Collect its properties. */
  342.       feat_value = decc$feature_get_value( feat_index, 1);
  343.       feat_value_min = decc$feature_get_value( feat_index, 2);
  344.       feat_value_max = decc$feature_get_value( feat_index, 3);
  345.  
  346.       if ((decc_feat_array[ i].value >= feat_value_min) &&
  347.        (decc_feat_array[ i].value <= feat_value_max))
  348.          {
  349.          /* Valid value.  Set it if necessary. */
  350.          if (feat_value != decc_feat_array[ i].value)
  351.             {
  352.             sts = decc$feature_set_value( feat_index,
  353.              1,
  354.              decc_feat_array[ i].value);
  355.             }
  356.          }
  357.       else
  358.          {
  359.          /* Invalid DECC feature value. */
  360.          printf( " INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
  361.           feat_value,
  362.           feat_value_min, decc_feat_array[ i].name, feat_value_max);
  363.          }
  364.       }
  365.    else
  366.       {
  367.       /* Invalid DECC feature name. */
  368.       printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[ i].name);
  369.       }
  370.    }
  371. }
  372.  
  373. /* Get "vms_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
  374.  
  375. #pragma nostandard
  376.  
  377. /* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
  378.    other attributes.  Note that "nopic" is significant only on VAX.
  379. */
  380. #pragma extern_model save
  381.  
  382. #pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
  383. void (*const x_vms_init)() = vms_init;
  384.  
  385. #pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
  386. const int spare[ 8] = { 0 };
  387.  
  388. #pragma extern_model restore
  389.  
  390. /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
  391.  
  392. #pragma extern_model save
  393. int LIB$INITIALIZE(void);
  394. #pragma extern_model strict_refdef
  395. int dmy_lib$initialize = (int) LIB$INITIALIZE;
  396. #pragma extern_model restore
  397.  
  398. #pragma standard
  399.  
  400. #endif /* !defined( __VAX) && (__CRTL_VER >= 70301000) */
  401.  
  402.