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