home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / tmp4 / ckvrtl.c < prev    next >
C/C++ Source or Header  |  2007-02-27  |  12KB  |  437 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.  
  48. /* Use <iosbdef.h> if available.  Otherwise declare IOSB here. */
  49.  
  50. #if !defined( __VAX) && (__CRTL_VER >= 70000000)
  51. #include <iosbdef.h>
  52. #else /* __CRTL_VER >= 70000000 */
  53. typedef struct _iosb {
  54.         unsigned short int iosb$w_status; /* Final I/O status   */
  55.         unsigned short int iosb$w_bcnt; /* 16-bit byte count    */
  56.         unsigned int iosb$l_dev_depend; /* 32-bit dev dependent */
  57.     } IOSB;
  58. #endif /* !defined( __VAX) && (__CRTL_VER >= 70000000) */
  59.  
  60.  
  61. /* Ugly work-around for bad type in VAX <atrdef.h>. */
  62.  
  63. #ifdef __VAX
  64. #define UWA (unsigned int)
  65. #else /* def __VAX */
  66. #define UWA
  67. #endif /* def __VAX */
  68.  
  69.  
  70. /* Private utime() code. */
  71.  
  72. /* Use long name (NAML) structure only where available.
  73.    (This should be non-VAX with __CRTL_VER >= 70200000.)
  74. */
  75.  
  76. #ifdef NAML$C_BID
  77.  
  78. /* Use long name (NAML) structure. */
  79.  
  80. #define FAB$L_NAMX fab$l_naml
  81. #define NAMX NAML
  82. #define NAMX$C_MAXRSS NAML$C_MAXRSS
  83. #define NAMX$B_DEV naml$l_long_dev_size
  84. #define NAMX$L_DEV naml$l_long_dev
  85. #define NAMX$L_ESA naml$l_long_expand
  86. #define NAMX$B_ESL naml$l_long_expand_size
  87. #define NAMX$B_ESS naml$l_long_expand_alloc
  88. #define NAMX$W_FID naml$w_fid
  89. #define NAMX$L_RSA naml$l_long_result
  90. #define NAMX$B_RSL naml$l_long_result_size
  91. #define NAMX$B_RSS naml$l_long_result_alloc
  92. #define CC$RMS_NAMX cc$rms_naml
  93.  
  94. #else /* def NAML$C_BID */
  95.  
  96. /* Use short name (NAM) structure. */
  97.  
  98. #define FAB$L_NAMX fab$l_nam
  99. #define NAMX NAM
  100. #define NAMX$C_MAXRSS NAM$C_MAXRSS
  101. #define NAMX$B_DEV nam$b_dev
  102. #define NAMX$L_DEV nam$l_dev
  103. #define NAMX$L_ESA nam$l_esa
  104. #define NAMX$B_ESL nam$b_esl
  105. #define NAMX$B_ESS nam$b_ess
  106. #define NAMX$W_FID nam$w_fid
  107. #define NAMX$L_RSA nam$l_rsa
  108. #define NAMX$B_RSL nam$b_rsl
  109. #define NAMX$B_RSS nam$b_rss
  110. #define CC$RMS_NAMX cc$rms_nam
  111.  
  112. #endif /* def NAML$C_BID */
  113.  
  114. /*--------------------------------------------------------------------*/
  115.  
  116. /* Private utime() code. */
  117.  
  118. /* Action routine for decc$to_vms(), in utime(). */
  119.  
  120. char vms_path[ NAMX$C_MAXRSS+ 1];
  121.  
  122. int set_vms_name( char *name, int type)
  123. {
  124.    strncpy( vms_path, name, NAMX$C_MAXRSS);
  125.    vms_path[ NAMX$C_MAXRSS] = '\0';
  126.    return 1;
  127. }
  128.  
  129. /*--------------------------------------------------------------------*/
  130.  
  131. /* utime() replacement. */
  132.  
  133. int vms_utime( const char *path, const struct utimbuf *times)
  134. {
  135. time_t utc_unsigned;
  136.  
  137. int chan, i;
  138. int sts, sts2;
  139.  
  140. unsigned short int vms_num_vec_time[ 7];
  141. unsigned int vms_abs_time[ 2];
  142. struct tm *tms;
  143. struct _iosb iosb_q;
  144.  
  145. /* QIOW item list used to set creation and revision dates. */
  146.  
  147. struct atrdef ut_atr[ 3] = {
  148.  {sizeof( vms_abs_time), ATR$C_CREDATE, UWA vms_abs_time},
  149.  {sizeof( vms_abs_time), ATR$C_REVDATE, UWA vms_abs_time},
  150.  {0,0,0}};
  151.  
  152. /* Various RMS structures used for file access. */
  153.  
  154. struct FAB ut_fab = cc$rms_fab;
  155. struct RAB ut_rab = cc$rms_rab;
  156. struct NAMX ut_namx = CC$RMS_NAMX;
  157. static struct fibdef ut_fib;
  158.  
  159. /* Device and file name buffers and their descriptors. */
  160.  
  161. static char dev_namx[ NAMX$C_MAXRSS+ 1];
  162. char esa_namx[ NAMX$C_MAXRSS+ 1];
  163. char rsa_namx[ NAMX$C_MAXRSS+ 1];
  164.  
  165. struct dsc$descriptor dev_dsc =
  166.  {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, dev_namx};
  167.  
  168. struct dsc$descriptor fib_dsc =
  169.  {sizeof( ut_fib), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &ut_fib};
  170.  
  171. /* We will accept either a UNIX-like path name or a VMS-like path name. 
  172.    If a slash is found in the name, assume that it's UNIX-like, and
  173.    convert it to VMS form.  Otherwise, use it as-is.
  174. */
  175.  
  176. if (strchr( path, '/') != NULL)
  177.    {
  178.    sts = decc$to_vms( path, set_vms_name, 0, 0);
  179.    path = vms_path;
  180.    }
  181.  
  182. /* Install the VMS file specification into the FAB. */
  183.  
  184. ut_fab.fab$l_fna = (char *) path;
  185. ut_fab.fab$b_fns = (unsigned char) strlen( path);
  186.  
  187. ut_fab.fab$l_dna = "";
  188. ut_fab.fab$b_dns = 0;
  189.  
  190. /* Point the FAB to the NAMX. */
  191.  
  192. ut_fab.FAB$L_NAMX = &ut_namx;
  193.  
  194. /* Install the name buffers into the NAM. */
  195.  
  196. ut_namx.NAMX$L_ESA = esa_namx;
  197. ut_namx.NAMX$B_ESL = 0;
  198. ut_namx.NAMX$B_ESS = sizeof( esa_namx)- 1;
  199.  
  200. ut_namx.NAMX$L_RSA = rsa_namx;
  201. ut_namx.NAMX$B_RSL = 0;
  202. ut_namx.NAMX$B_RSS = sizeof( rsa_namx)- 1;
  203.  
  204. /* Convert the modification time (UTC time_t) to local "tm" time. */
  205.  
  206. tms = localtime( &(times-> modtime));
  207.  
  208. /* Move (translate) "tm" structure local time to VMS vector time. */
  209.  
  210. if (tms != NULL)
  211.    {
  212.    vms_num_vec_time[ 0] = tms-> tm_year+ 1900;
  213.    vms_num_vec_time[ 1] = tms-> tm_mon+ 1;
  214.    vms_num_vec_time[ 2] = tms-> tm_mday;
  215.    vms_num_vec_time[ 3] = tms-> tm_hour;
  216.    vms_num_vec_time[ 4] = tms-> tm_min;
  217.    vms_num_vec_time[ 5] = tms-> tm_sec;
  218.    vms_num_vec_time[ 6] = 0;  /* centiseconds */
  219.  
  220. /* Convert VMS vector time to VMS absolute time (quadword). */
  221.  
  222.    sts = lib$cvt_vectim( vms_num_vec_time, vms_abs_time);
  223.  
  224.    if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  225.       {
  226. /* Parse the file specification. */
  227.  
  228.       sts = sys$parse( &ut_fab, 0, 0);
  229.  
  230.       if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  231.          {
  232. /* Locate the file. (Gets the FID.) */
  233.  
  234.          sts = sys$search( &ut_fab, 0, 0);
  235.  
  236.          if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  237.             {
  238. /* Form the device name descriptor. */
  239.  
  240.             dev_dsc.dsc$w_length = ut_namx.NAMX$B_DEV;
  241.             dev_dsc.dsc$a_pointer = (char *) ut_namx.NAMX$L_DEV;
  242.  
  243. /* Assign a channel to the disk device. */
  244.  
  245.             sts = sys$assign( &dev_dsc, &chan, 0, 0);
  246.  
  247.             if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  248.                {
  249. /* Move the FID (and not the DID) into the FIB. */
  250.  
  251.                memset( (void *) &ut_fib, 0, sizeof( ut_fib));
  252.  
  253.                for (i = 0; i < 3; i++)
  254.                   {
  255.                   ut_fib.fib$w_fid[ i] = ut_namx.NAMX$W_FID[ i];
  256.                   ut_fib.fib$w_did[ i] = 0;
  257.                   }
  258.  
  259. /* Prevent this QIOW from setting the revision time to now. */
  260.  
  261.                ut_fib.fib$l_acctl = FIB$M_NORECORD;
  262.  
  263. /* Set the file dates. */
  264.  
  265.                sts = sys$qiow( 0,
  266.                                chan,
  267.                                IO$_MODIFY,
  268.                                &iosb_q,
  269.                                0,
  270.                                0,
  271.                                &fib_dsc,
  272.                                0,
  273.                                0,
  274.                                0,
  275.                                ut_atr,
  276.                                0);
  277.  
  278.                if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  279.                   {
  280.                    sts = iosb_q.iosb$w_status;
  281.                   }
  282.                sts2 = sys$dassgn( chan);
  283.  
  284.                if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  285.                   {
  286.                   sts = sts2;
  287.                   }
  288.                }
  289.             }
  290.          }
  291.       }
  292.    }
  293.  
  294. /* Convert successful VMS status to zero = success status.
  295.    If failure, set errno and vaxc$errno, and return -1 = failure status.
  296. */
  297.  
  298. if ((sts& STS$M_SEVERITY) == STS$K_SUCCESS)
  299.    {
  300.    sts = 0;
  301.    }
  302. else
  303.    {
  304.    errno = EVMSERR;
  305.    vaxc$errno = sts;
  306.    sts = -1;
  307.    }
  308.  
  309. return sts;
  310. }
  311.  
  312. #endif /* __CRTL_VER >= 70300000 [else] */
  313.  
  314. /**********************************************************************/
  315.  
  316. #if !defined( __VAX) && (__CRTL_VER >= 70301000)
  317.  
  318. #include <stdio.h>
  319. #include <unixlib.h>
  320.  
  321. /* Flag to sense if vms_init() was called.  (Handy for debug.) */
  322.  
  323. int vms_init_done = -1;
  324.  
  325.  
  326. /* vms_init()
  327.  
  328.       Uses LIB$INITIALIZE to set a collection of C RTL features without
  329.       requiring the user to define the corresponding logical names.
  330. */
  331.  
  332. /* Structure to hold a DECC$* feature name and its desired value. */
  333.  
  334. typedef struct
  335.    {
  336.    char *name;
  337.    int value;
  338.    } decc_feat_t;
  339.  
  340. /* Array of DECC$* feature names and their desired values. */
  341.  
  342. decc_feat_t decc_feat_array[] = {
  343.    /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
  344.  { "DECC$ARGV_PARSE_STYLE", 1 },
  345.    /* Preserve case for file names on ODS5 disks. */
  346.  { "DECC$EFS_CASE_PRESERVE", 1 },
  347.    /* Enable multiple dots (and most characters) in ODS5 file names,
  348.       while preserving VMS-ness of ";version". */
  349.  { "DECC$EFS_CHARSET", 1 },
  350.    /* List terminator. */
  351.  { (char *)NULL, 0 } };
  352.  
  353. /* LIB$INITIALIZE initialization function. */
  354.  
  355. static void vms_init( void)
  356. {
  357. int feat_index;
  358. int feat_value;
  359. int feat_value_max;
  360. int feat_value_min;
  361. int i;
  362. int sts;
  363.  
  364. /* Set the global flag to indicate that LIB$INITIALIZE worked. */
  365.  
  366. vms_init_done = 1;
  367.  
  368. /* Loop through all items in the decc_feat_array[]. */
  369.  
  370. for (i = 0; decc_feat_array[ i].name != NULL; i++)
  371.    {
  372.    /* Get the feature index. */
  373.    feat_index = decc$feature_get_index( decc_feat_array[ i].name);
  374.    if (feat_index >= 0)
  375.       {
  376.       /* Valid item.  Collect its properties. */
  377.       feat_value = decc$feature_get_value( feat_index, 1);
  378.       feat_value_min = decc$feature_get_value( feat_index, 2);
  379.       feat_value_max = decc$feature_get_value( feat_index, 3);
  380.  
  381.       if ((decc_feat_array[ i].value >= feat_value_min) &&
  382.        (decc_feat_array[ i].value <= feat_value_max))
  383.          {
  384.          /* Valid value.  Set it if necessary. */
  385.          if (feat_value != decc_feat_array[ i].value)
  386.             {
  387.             sts = decc$feature_set_value( feat_index,
  388.              1,
  389.              decc_feat_array[ i].value);
  390.             }
  391.          }
  392.       else
  393.          {
  394.          /* Invalid DECC feature value. */
  395.          printf( " INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
  396.           feat_value,
  397.           feat_value_min, decc_feat_array[ i].name, feat_value_max);
  398.          }
  399.       }
  400.    else
  401.       {
  402.       /* Invalid DECC feature name. */
  403.       printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[ i].name);
  404.       }
  405.    }
  406. }
  407.  
  408. /* Get "vms_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
  409.  
  410. #pragma nostandard
  411.  
  412. /* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
  413.    other attributes.  Note that "nopic" is significant only on VAX.
  414. */
  415. #pragma extern_model save
  416.  
  417. #pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
  418. void (*const x_vms_init)() = vms_init;
  419.  
  420. #pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
  421. const int spare[ 8] = { 0 };
  422.  
  423. #pragma extern_model restore
  424.  
  425. /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
  426.  
  427. #pragma extern_model save
  428. int LIB$INITIALIZE(void);
  429. #pragma extern_model strict_refdef
  430. int dmy_lib$initialize = (int) LIB$INITIALIZE;
  431. #pragma extern_model restore
  432.  
  433. #pragma standard
  434.  
  435. #endif /* !defined( __VAX) && (__CRTL_VER >= 70301000) */
  436.  
  437.