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