xref: /openbsd-src/gnu/usr.bin/cvs/lib/system.h (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* system-dependent definitions for CVS.
2    Copyright (C) 1989-1992 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.  */
13 
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 
17 #ifdef STAT_MACROS_BROKEN
18 #undef S_ISBLK
19 #undef S_ISCHR
20 #undef S_ISDIR
21 #undef S_ISREG
22 #undef S_ISFIFO
23 #undef S_ISLNK
24 #undef S_ISSOCK
25 #undef S_ISMPB
26 #undef S_ISMPC
27 #undef S_ISNWK
28 #endif
29 
30 /* Not all systems have S_IFMT, but we want to use it if we have it.
31    The S_IFMT code below looks right (it masks and compares).  The
32    non-S_IFMT code looks bogus (are there really systems on which
33    S_IFBLK, S_IFLNK, &c, each have their own bit?  I suspect it was
34    written for OS/2 using the IBM C/C++ Tools 2.01 compiler).
35 
36    Of course POSIX systems will have S_IS*, so maybe the issue is
37    semi-moot.  */
38 
39 #if !defined(S_ISBLK) && defined(S_IFBLK)
40 # if defined(S_IFMT)
41 # define	S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
42 # else
43 # define S_ISBLK(m) ((m) & S_IFBLK)
44 # endif
45 #endif
46 
47 #if !defined(S_ISCHR) && defined(S_IFCHR)
48 # if defined(S_IFMT)
49 # define	S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
50 # else
51 # define S_ISCHR(m) ((m) & S_IFCHR)
52 # endif
53 #endif
54 
55 #if !defined(S_ISDIR) && defined(S_IFDIR)
56 # if defined(S_IFMT)
57 # define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
58 # else
59 # define S_ISDIR(m) ((m) & S_IFDIR)
60 # endif
61 #endif
62 
63 #if !defined(S_ISREG) && defined(S_IFREG)
64 # if defined(S_IFMT)
65 # define	S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
66 # else
67 # define S_ISREG(m) ((m) & S_IFREG)
68 # endif
69 #endif
70 
71 #if !defined(S_ISFIFO) && defined(S_IFIFO)
72 # if defined(S_IFMT)
73 # define	S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
74 # else
75 # define S_ISFIFO(m) ((m) & S_IFIFO)
76 # endif
77 #endif
78 
79 #if !defined(S_ISLNK) && defined(S_IFLNK)
80 # if defined(S_IFMT)
81 # define	S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
82 # else
83 # define S_ISLNK(m) ((m) & S_IFLNK)
84 # endif
85 #endif
86 
87 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
88 # if defined(S_IFMT)
89 # define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
90 # else
91 # define S_ISSOCK(m) ((m) & S_IFSOCK)
92 # endif
93 #endif
94 
95 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
96 # if defined(S_IFMT)
97 # define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
98 # define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
99 # else
100 # define S_ISMPB(m) ((m) & S_IFMPB)
101 # define S_ISMPC(m) ((m) & S_IFMPC)
102 # endif
103 #endif
104 
105 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
106 # if defined(S_IFMT)
107 # define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
108 # else
109 # define S_ISNWK(m) ((m) & S_IFNWK)
110 # endif
111 #endif
112 
113 #ifdef NEED_DECOY_PERMISSIONS        /* OS/2, really */
114 
115 #define	S_IRUSR S_IREAD
116 #define	S_IWUSR S_IWRITE
117 #define	S_IXUSR S_IEXEC
118 #define	S_IRWXU	(S_IRUSR | S_IWUSR | S_IXUSR)
119 #define	S_IRGRP S_IREAD
120 #define	S_IWGRP S_IWRITE
121 #define	S_IXGRP S_IEXEC
122 #define	S_IRWXG	(S_IRGRP | S_IWGRP | S_IXGRP)
123 #define	S_IROTH S_IREAD
124 #define	S_IWOTH S_IWRITE
125 #define	S_IXOTH S_IEXEC
126 #define	S_IRWXO	(S_IROTH | S_IWOTH | S_IXOTH)
127 
128 #else /* ! NEED_DECOY_PERMISSIONS */
129 
130 #ifndef S_IRUSR
131 #define	S_IRUSR 0400
132 #define	S_IWUSR 0200
133 #define	S_IXUSR 0100
134 /* Read, write, and execute by owner.  */
135 #define	S_IRWXU	(S_IRUSR|S_IWUSR|S_IXUSR)
136 
137 #define	S_IRGRP	(S_IRUSR >> 3)	/* Read by group.  */
138 #define	S_IWGRP	(S_IWUSR >> 3)	/* Write by group.  */
139 #define	S_IXGRP	(S_IXUSR >> 3)	/* Execute by group.  */
140 /* Read, write, and execute by group.  */
141 #define	S_IRWXG	(S_IRWXU >> 3)
142 
143 #define	S_IROTH	(S_IRGRP >> 3)	/* Read by others.  */
144 #define	S_IWOTH	(S_IWGRP >> 3)	/* Write by others.  */
145 #define	S_IXOTH	(S_IXGRP >> 3)	/* Execute by others.  */
146 /* Read, write, and execute by others.  */
147 #define	S_IRWXO	(S_IRWXG >> 3)
148 #endif /* !def S_IRUSR */
149 #endif /* NEED_DECOY_PERMISSIONS */
150 
151 #if defined(POSIX) || defined(HAVE_UNISTD_H)
152 #include <unistd.h>
153 #include <limits.h>
154 #else
155 off_t lseek ();
156 char *getcwd ();
157 #endif
158 
159 #if TIME_WITH_SYS_TIME
160 # include <sys/time.h>
161 # include <time.h>
162 #else
163 # if HAVE_SYS_TIME_H
164 #  include <sys/time.h>
165 # else
166 #  include <time.h>
167 # endif
168 #endif
169 
170 #ifdef HAVE_IO_H
171 #include <io.h>
172 #endif
173 
174 #ifdef HAVE_DIRECT_H
175 #include <direct.h>
176 #endif
177 
178 #ifdef timezone
179 #undef timezone /* needed for sgi */
180 #endif
181 
182 #ifdef HAVE_SYS_TIMEB_H
183 #include <sys/timeb.h>
184 #else
185 struct timeb {
186     time_t		time;		/* Seconds since the epoch	*/
187     unsigned short	millitm;	/* Field not used		*/
188     short		timezone;
189     short		dstflag;	/* Field not used		*/
190 };
191 #endif
192 
193 #if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE)
194 #if !defined(timezone)
195 extern long timezone;
196 #endif
197 #endif
198 
199 
200 /*
201 **  MAXPATHLEN and PATH_MAX
202 **
203 **     On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of
204 **     those that this is not true, again most define PATH_MAX in limits.h
205 **     or sys/limits.h which usually gets included by limits.h. On the few
206 **     remaining systems that neither statement is true, _POSIX_PATH_MAX
207 **     is defined.
208 **
209 **     So:
210 **         1. If PATH_MAX is defined just use it.
211 **         2. If MAXPATHLEN is defined but not PATH_MAX, then define
212 **            PATH_MAX in terms of MAXPATHLEN.
213 **         3. If neither is defined, include limits.h and check for
214 **            PATH_MAX again.
215 **         3.1 If we now have PATHSIZE, define PATH_MAX in terms of that.
216 **             and ignore the rest.  Since _POSIX_PATH_MAX (checked for
217 **             next) is the *most* restrictive (smallest) value, if we
218 **             trust _POSIX_PATH_MAX, several of our buffers are too small.
219 **         4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is,
220 **            then define PATH_MAX in terms of _POSIX_PATH_MAX.
221 **         5. And if even _POSIX_PATH_MAX doesn't exist just put in
222 **            a reasonable value.
223 **         *. All in all, this is an excellent argument for using pathconf()
224 **            when at all possible.  Or better yet, dynamically allocate
225 **            our buffers and use getcwd() not getwd().
226 **
227 **     This works on:
228 **         Sun Sparc 10        SunOS 4.1.3  &  Solaris 1.2
229 **         HP 9000/700         HP/UX 8.07   &  HP/UX 9.01
230 **         Tektronix XD88/10   UTekV 3.2e
231 **         IBM RS6000          AIX 3.2
232 **         Dec Alpha           OSF 1 ????
233 **         Intel 386           BSDI BSD/386
234 **         Intel 386           SCO OpenServer Release 5
235 **         Apollo              Domain 10.4
236 **         NEC                 SVR4
237 */
238 
239 /* On MOST systems this will get you MAXPATHLEN.
240    Windows NT doesn't have this file, tho.  */
241 #ifdef HAVE_SYS_PARAM_H
242 #include <sys/param.h>
243 #endif
244 
245 #ifndef PATH_MAX
246 #  ifdef MAXPATHLEN
247 #    define PATH_MAX                 MAXPATHLEN
248 #  else
249 #    include <limits.h>
250 #    ifndef PATH_MAX
251 #      ifdef PATHSIZE
252 #         define PATH_MAX               PATHSIZE
253 #      else /* no PATHSIZE */
254 #        ifdef _POSIX_PATH_MAX
255 #          define PATH_MAX             _POSIX_PATH_MAX
256 #        else
257 #          define PATH_MAX             1024
258 #        endif  /* no _POSIX_PATH_MAX */
259 #      endif  /* no PATHSIZE */
260 #    endif /* no PATH_MAX   */
261 #  endif  /* MAXPATHLEN */
262 #endif  /* PATH_MAX   */
263 
264 
265 /* The NeXT (without _POSIX_SOURCE, which we don't want) has a utime.h
266    which doesn't define anything.  It would be cleaner to have configure
267    check for struct utimbuf, but for now I'm checking NeXT here (so I don't
268    have to debug the configure check across all the machines).  */
269 #if defined (HAVE_UTIME_H) && !defined (NeXT)
270 #  include <utime.h>
271 #else
272 #  if defined (HAVE_SYS_UTIME_H)
273 #    include <sys/utime.h>
274 #  else
275 #    ifndef ALTOS
276 struct utimbuf
277 {
278   long actime;
279   long modtime;
280 };
281 #    endif
282 int utime ();
283 #  endif
284 #endif
285 
286 #include <string.h>
287 
288 #ifndef ERRNO_H_MISSING
289 #include <errno.h>
290 #endif
291 
292 /* Not all systems set the same error code on a non-existent-file
293    error.  This tries to ask the question somewhat portably.
294    On systems that don't have ENOTEXIST, this should behave just like
295    x == ENOENT.  "x" is probably errno, of course. */
296 
297 #ifdef ENOTEXIST
298 #  ifdef EOS2ERR
299 #    define existence_error(x) \
300      (((x) == ENOTEXIST) || ((x) == ENOENT) || ((x) == EOS2ERR))
301 #  else
302 #    define existence_error(x) \
303      (((x) == ENOTEXIST) || ((x) == ENOENT))
304 #  endif
305 #else
306 #  ifdef EVMSERR
307 #     define existence_error(x) \
308 ((x) == ENOENT || (x) == EINVAL || (x) == EVMSERR)
309 #  else
310 #    define existence_error(x) ((x) == ENOENT)
311 #  endif
312 #endif
313 
314 
315 #ifdef STDC_HEADERS
316 #include <stdlib.h>
317 #else
318 char *getenv ();
319 char *malloc ();
320 char *realloc ();
321 char *calloc ();
322 extern int errno;
323 #endif
324 
325 /* SunOS4 apparently does not define this in stdlib.h.  */
326 #ifndef EXIT_FAILURE
327 #define EXIT_FAILURE 1
328 #endif
329 
330 /* check for POSIX signals */
331 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK)
332 # define POSIX_SIGNALS
333 #endif
334 
335 /* MINIX 1.6 doesn't properly support sigaction */
336 #if defined(_MINIX)
337 # undef POSIX_SIGNALS
338 #endif
339 
340 /* If !POSIX, try for BSD.. Reason: 4.4BSD implements these as wrappers */
341 #if !defined(POSIX_SIGNALS)
342 # if defined(HAVE_SIGVEC) && defined(HAVE_SIGSETMASK) && defined(HAVE_SIGBLOCK)
343 #  define BSD_SIGNALS
344 # endif
345 #endif
346 
347 /* Under OS/2, this must be included _after_ stdio.h; that's why we do
348    it here. */
349 #ifdef USE_OWN_TCPIP_H
350 #include "tcpip.h"
351 #endif
352 
353 #ifdef HAVE_FCNTL_H
354 #include <fcntl.h>
355 #else
356 #include <sys/file.h>
357 #endif
358 
359 #ifndef SEEK_SET
360 #define SEEK_SET 0
361 #define SEEK_CUR 1
362 #define SEEK_END 2
363 #endif
364 
365 #ifndef F_OK
366 #define F_OK 0
367 #define X_OK 1
368 #define W_OK 2
369 #define R_OK 4
370 #endif
371 
372 #if HAVE_DIRENT_H
373 # include <dirent.h>
374 # define NAMLEN(dirent) strlen((dirent)->d_name)
375 #else
376 # define dirent direct
377 # define NAMLEN(dirent) (dirent)->d_namlen
378 # if HAVE_SYS_NDIR_H
379 #  include <sys/ndir.h>
380 # endif
381 # if HAVE_SYS_DIR_H
382 #  include <sys/dir.h>
383 # endif
384 # if HAVE_NDIR_H
385 #  include <ndir.h>
386 # endif
387 #endif
388 
389 /* Convert B 512-byte blocks to kilobytes if K is nonzero,
390    otherwise return it unchanged. */
391 #define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
392 
393 #ifndef S_ISLNK
394 #define lstat stat
395 #endif
396 
397 /*
398  * Some UNIX distributions don't include these in their stat.h Defined here
399  * because "config.h" is always included last.
400  */
401 #ifndef S_IWRITE
402 #define	S_IWRITE	0000200		/* write permission, owner */
403 #endif
404 #ifndef S_IWGRP
405 #define	S_IWGRP		0000020		/* write permission, grougroup */
406 #endif
407 #ifndef S_IWOTH
408 #define	S_IWOTH		0000002		/* write permission, other */
409 #endif
410 
411 /* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem
412    calls take  only one argument; permission is handled very differently on
413    those systems than in Unix.  So we leave such systems a hook on which they
414    can hang their own definitions.  */
415 
416 #ifndef CVS_ACCESS
417 #define CVS_ACCESS access
418 #endif
419 
420 #ifndef CVS_CHDIR
421 #define CVS_CHDIR chdir
422 #endif
423 
424 #ifndef CVS_CREAT
425 #define CVS_CREAT creat
426 #endif
427 
428 #ifndef CVS_FOPEN
429 #define CVS_FOPEN fopen
430 #endif
431 
432 #ifndef CVS_MKDIR
433 #define CVS_MKDIR mkdir
434 #endif
435 
436 #ifndef CVS_OPEN
437 #define CVS_OPEN open
438 #endif
439 
440 #ifndef CVS_OPENDIR
441 #define CVS_OPENDIR opendir
442 #endif
443 
444 #ifndef CVS_RENAME
445 #define CVS_RENAME rename
446 #endif
447 
448 #ifndef CVS_RMDIR
449 #define CVS_RMDIR rmdir
450 #endif
451 
452 #ifndef CVS_STAT
453 #define CVS_STAT stat
454 #endif
455 
456 /* Open question: should CVS_STAT be lstat by default?  We need
457    to use lstat in order to handle symbolic links correctly with
458    the PreservePermissions option. -twp */
459 #ifndef CVS_LSTAT
460 #define CVS_LSTAT lstat
461 #endif
462 
463 #ifndef CVS_UNLINK
464 #define CVS_UNLINK unlink
465 #endif
466 
467 /* Wildcard matcher.  Should be case-insensitive if the system is.  */
468 #ifndef CVS_FNMATCH
469 #define CVS_FNMATCH fnmatch
470 #endif
471 
472 #if defined (__CYGWIN32__) || defined (WIN32)
473 
474 /* Under Windows NT, filenames are case-insensitive, and both / and \
475    are path component separators.  */
476 
477 #define FOLD_FN_CHAR(c) (WNT_filename_classes[(unsigned char) (c)])
478 extern unsigned char WNT_filename_classes[];
479 #define FILENAMES_CASE_INSENSITIVE 1
480 
481 /* Is the character C a path name separator?  Under
482    Windows NT, you can use either / or \.  */
483 #define ISDIRSEP(c) (FOLD_FN_CHAR(c) == '/')
484 
485 /* Like strcmp, but with the appropriate tweaks for file names.
486    Under Windows NT, filenames are case-insensitive but case-preserving,
487    and both \ and / are path element separators.  */
488 extern int fncmp (const char *n1, const char *n2);
489 
490 /* Fold characters in FILENAME to their canonical forms.
491    If FOLD_FN_CHAR is not #defined, the system provides a default
492    definition for this.  */
493 extern void fnfold (char *FILENAME);
494 
495 #endif /* defined (__CYGWIN32__) || defined (WIN32) */
496 
497 /* Some file systems are case-insensitive.  If FOLD_FN_CHAR is
498    #defined, it maps the character C onto its "canonical" form.  In a
499    case-insensitive system, it would map all alphanumeric characters
500    to lower case.  Under Windows NT, / and \ are both path component
501    separators, so FOLD_FN_CHAR would map them both to /.  */
502 #ifndef FOLD_FN_CHAR
503 #define FOLD_FN_CHAR(c) (c)
504 #define fnfold(filename) (filename)
505 #define fncmp strcmp
506 #endif
507 
508 /* Different file systems have different path component separators.
509    For the VMS port we might need to abstract further back than this.  */
510 #ifndef ISDIRSEP
511 #define ISDIRSEP(c) ((c) == '/')
512 #endif
513 
514 
515 /* On some systems, we have to be careful about writing/reading files
516    in text or binary mode (so in text mode the system can handle CRLF
517    vs. LF, VMS text file conventions, &c).  We decide to just always
518    be careful.  That way we don't have to worry about whether text and
519    binary differ on this system.  We just have to worry about whether
520    the system has O_BINARY and "rb".  The latter is easy; all ANSI C
521    libraries have it, SunOS4 has it, and CVS has used it unguarded
522    some places for a while now without complaints (e.g. "rb" in
523    server.c (server_updated), since CVS 1.8).  The former is just an
524    #ifdef.  */
525 
526 #define FOPEN_BINARY_READ ("rb")
527 #define FOPEN_BINARY_WRITE ("wb")
528 
529 #ifdef O_BINARY
530 #define OPEN_BINARY (O_BINARY)
531 #else
532 #define OPEN_BINARY (0)
533 #endif
534