Home | History | Annotate | Download | only in make-3.81
      1 /* VMS functions
      2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      3 2006 Free Software Foundation, Inc.
      4 This file is part of GNU Make.
      5 
      6 GNU Make is free software; you can redistribute it and/or modify it under the
      7 terms of the GNU General Public License as published by the Free Software
      8 Foundation; either version 2, or (at your option) any later version.
      9 
     10 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
     11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License along with
     15 GNU Make; see the file COPYING.  If not, write to the Free Software
     16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
     17 
     18 #include "make.h"
     19 #include "debug.h"
     20 #include "job.h"
     21 
     22 #ifdef __DECC
     23 #include <starlet.h>
     24 #endif
     25 #include <descrip.h>
     26 #include <rms.h>
     27 #include <iodef.h>
     28 #include <atrdef.h>
     29 #include <fibdef.h>
     30 #include "vmsdir.h"
     31 
     32 #ifdef HAVE_VMSDIR_H
     33 
     34 DIR *
     35 opendir (char *dspec)
     36 {
     37   struct DIR *dir  = (struct DIR *)xmalloc (sizeof (struct DIR));
     38   struct NAM *dnam = (struct NAM *)xmalloc (sizeof (struct NAM));
     39   struct FAB *dfab = &dir->fab;
     40   char *searchspec = (char *)xmalloc (MAXNAMLEN + 1);
     41 
     42   memset (dir, 0, sizeof *dir);
     43 
     44   *dfab = cc$rms_fab;
     45   *dnam = cc$rms_nam;
     46   sprintf (searchspec, "%s*.*;", dspec);
     47 
     48   dfab->fab$l_fna = searchspec;
     49   dfab->fab$b_fns = strlen (searchspec);
     50   dfab->fab$l_nam = dnam;
     51 
     52   *dnam = cc$rms_nam;
     53   dnam->nam$l_esa = searchspec;
     54   dnam->nam$b_ess = MAXNAMLEN;
     55 
     56   if (! (sys$parse (dfab) & 1))
     57     {
     58       free (dir);
     59       free (dnam);
     60       free (searchspec);
     61       return (NULL);
     62     }
     63 
     64   return dir;
     65 }
     66 
     67 #define uppercasify(str) \
     68   do \
     69     { \
     70       char *tmp; \
     71       for (tmp = (str); *tmp != '\0'; tmp++) \
     72         if (islower ((unsigned char)*tmp)) \
     73           *tmp = toupper ((unsigned char)*tmp); \
     74     } \
     75   while (0)
     76 
     77 struct direct *
     78 readdir (DIR *dir)
     79 {
     80   struct FAB *dfab = &dir->fab;
     81   struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam);
     82   struct direct *dentry = &dir->dir;
     83   int i;
     84 
     85   memset (dentry, 0, sizeof *dentry);
     86 
     87   dnam->nam$l_rsa = dir->d_result;
     88   dnam->nam$b_rss = MAXNAMLEN;
     89 
     90   DB (DB_VERBOSE, ("."));
     91 
     92   if (!((i = sys$search (dfab)) & 1))
     93     {
     94       DB (DB_VERBOSE, (_("sys$search failed with %d\n"), i));
     95       return (NULL);
     96     }
     97 
     98   dentry->d_off = 0;
     99   if (dnam->nam$w_fid == 0)
    100     dentry->d_fileno = 1;
    101   else
    102     dentry->d_fileno = dnam->nam$w_fid[0] + (dnam->nam$w_fid[1] << 16);
    103 
    104   dentry->d_reclen = sizeof (struct direct);
    105   dentry->d_namlen = dnam->nam$b_name + dnam->nam$b_type;
    106   strncpy (dentry->d_name, dnam->nam$l_name, dentry->d_namlen);
    107   dentry->d_name[dentry->d_namlen] = '\0';
    108 
    109 #ifdef HAVE_CASE_INSENSITIVE_FS
    110   uppercasify (dentry->d_name);
    111 #endif
    112 
    113   return (dentry);
    114 }
    115 
    116 int
    117 closedir (DIR *dir)
    118 {
    119   if (dir != NULL)
    120     {
    121       struct FAB *dfab = &dir->fab;
    122       struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam);
    123       if (dnam != NULL)
    124 	free (dnam->nam$l_esa);
    125       free (dnam);
    126       free (dir);
    127     }
    128 
    129   return 0;
    130 }
    131 #endif /* compiled for OpenVMS prior to V7.x */
    132 
    133 char *
    134 getwd (char *cwd)
    135 {
    136   static char buf[512];
    137 
    138   if (cwd)
    139     return (getcwd (cwd, 512));
    140   else
    141     return (getcwd (buf, 512));
    142 }
    143 
    144 int
    145 vms_stat (char *name, struct stat *buf)
    146 {
    147   int status;
    148   int i;
    149 
    150   static struct FAB Fab;
    151   static struct NAM Nam;
    152   static struct fibdef Fib;	/* short fib */
    153   static struct dsc$descriptor FibDesc =
    154   { sizeof (Fib), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *) &Fib };
    155   static struct dsc$descriptor_s DevDesc =
    156   { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &Nam.nam$t_dvi[1] };
    157   static char EName[NAM$C_MAXRSS];
    158   static char RName[NAM$C_MAXRSS];
    159   static struct dsc$descriptor_s FileName =
    160   { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 };
    161   static struct dsc$descriptor_s string =
    162   { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 };
    163   static unsigned long Rdate[2];
    164   static unsigned long Cdate[2];
    165   static struct atrdef Atr[] =
    166   {
    167 #if defined(VAX)
    168     /* Revision date */
    169     { sizeof (Rdate), ATR$C_REVDATE, (unsigned int) &Rdate[0] },
    170     /* Creation date */
    171     { sizeof (Cdate), ATR$C_CREDATE, (unsigned int) &Cdate[0] },
    172 #else
    173     /* Revision date */
    174     { sizeof (Rdate), ATR$C_REVDATE, &Rdate[0] },
    175     /* Creation date */
    176     { sizeof (Cdate), ATR$C_CREDATE, &Cdate[0]},
    177 #endif
    178     { 0, 0, 0 }
    179   };
    180   static short int DevChan;
    181   static short int iosb[4];
    182 
    183   name = vmsify (name, 0);
    184 
    185   /* initialize RMS structures, we need a NAM to retrieve the FID */
    186   Fab = cc$rms_fab;
    187   Fab.fab$l_fna = name;		/* name of file */
    188   Fab.fab$b_fns = strlen (name);
    189   Fab.fab$l_nam = &Nam;		/* FAB has an associated NAM */
    190 
    191   Nam = cc$rms_nam;
    192   Nam.nam$l_esa = EName;	/* expanded filename */
    193   Nam.nam$b_ess = sizeof (EName);
    194   Nam.nam$l_rsa = RName;	/* resultant filename */
    195   Nam.nam$b_rss = sizeof (RName);
    196 
    197   /* do $PARSE and $SEARCH here */
    198   status = sys$parse (&Fab);
    199   if (!(status & 1))
    200     return -1;
    201 
    202   DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
    203   status = sys$assign (&DevDesc, &DevChan, 0, 0);
    204   if (!(status & 1))
    205     return -1;
    206 
    207   FileName.dsc$a_pointer = Nam.nam$l_name;
    208   FileName.dsc$w_length = Nam.nam$b_name + Nam.nam$b_type + Nam.nam$b_ver;
    209 
    210   /* Initialize the FIB */
    211   for (i = 0; i < 3; i++)
    212     {
    213 #ifndef __VAXC
    214       Fib.fib$w_fid[i] = Nam.nam$w_fid[i];
    215       Fib.fib$w_did[i] = Nam.nam$w_did[i];
    216 #else
    217       Fib.fib$r_fid_overlay.fib$w_fid[i] = Nam.nam$w_fid[i];
    218       Fib.fib$r_did_overlay.fib$w_did[i] = Nam.nam$w_did[i];
    219 #endif
    220     }
    221 
    222   status = sys$qiow (0, DevChan, IO$_ACCESS, &iosb, 0, 0,
    223 		     &FibDesc, &FileName, 0, 0, &Atr, 0);
    224   sys$dassgn (DevChan);
    225   if (!(status & 1))
    226     return -1;
    227   status = iosb[0];
    228   if (!(status & 1))
    229     return -1;
    230 
    231   status = stat (name, buf);
    232   if (status)
    233     return -1;
    234 
    235   buf->st_mtime = ((Rdate[0] >> 24) & 0xff) + ((Rdate[1] << 8) & 0xffffff00);
    236   buf->st_ctime = ((Cdate[0] >> 24) & 0xff) + ((Cdate[1] << 8) & 0xffffff00);
    237 
    238   return 0;
    239 }
    240 
    241 char *
    242 cvt_time (unsigned long tval)
    243 {
    244   static long int date[2];
    245   static char str[27];
    246   static struct dsc$descriptor date_str =
    247   { 26, DSC$K_DTYPE_T, DSC$K_CLASS_S, str };
    248 
    249   date[0] = (tval & 0xff) << 24;
    250   date[1] = ((tval >> 8) & 0xffffff);
    251 
    252   if ((date[0] == 0) && (date[1] == 0))
    253     return ("never");
    254 
    255   sys$asctim (0, &date_str, date, 0);
    256   str[26] = '\0';
    257 
    258   return (str);
    259 }
    260 
    261 int
    262 strcmpi (const char *s1, const char *s2)
    263 {
    264   while (*s1 != '\0' && toupper(*s1) == toupper(*s2))
    265     {
    266       s1++;
    267       s2++;
    268     }
    269 
    270   return toupper(*(unsigned char *) s1) - toupper(*(unsigned char *) s2);
    271 }
    272