xref: /openbsd/gnu/usr.bin/cvs/lib/system.h (revision 43c1707e)
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 #include "xtime.h"
160 
161 #ifdef HAVE_IO_H
162 #include <io.h>
163 #endif
164 
165 #ifdef HAVE_DIRECT_H
166 #include <direct.h>
167 #endif
168 
169 
170 
171 /*
172 **  MAXPATHLEN and PATH_MAX
173 **
174 **     On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of
175 **     those that this is not true, again most define PATH_MAX in limits.h
176 **     or sys/limits.h which usually gets included by limits.h. On the few
177 **     remaining systems that neither statement is true, _POSIX_PATH_MAX
178 **     is defined.
179 **
180 **     So:
181 **         1. If PATH_MAX is defined just use it.
182 **         2. If MAXPATHLEN is defined but not PATH_MAX, then define
183 **            PATH_MAX in terms of MAXPATHLEN.
184 **         3. If neither is defined, include limits.h and check for
185 **            PATH_MAX again.
186 **         3.1 If we now have PATHSIZE, define PATH_MAX in terms of that.
187 **             and ignore the rest.  Since _POSIX_PATH_MAX (checked for
188 **             next) is the *most* restrictive (smallest) value, if we
189 **             trust _POSIX_PATH_MAX, several of our buffers are too small.
190 **         4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is,
191 **            then define PATH_MAX in terms of _POSIX_PATH_MAX.
192 **         5. And if even _POSIX_PATH_MAX doesn't exist just put in
193 **            a reasonable value.
194 **         *. All in all, this is an excellent argument for using pathconf()
195 **            when at all possible.  Or better yet, dynamically allocate
196 **            our buffers and use getcwd() not getwd().
197 **
198 **     This works on:
199 **         Sun Sparc 10        SunOS 4.1.3  &  Solaris 1.2
200 **         HP 9000/700         HP/UX 8.07   &  HP/UX 9.01
201 **         Tektronix XD88/10   UTekV 3.2e
202 **         IBM RS6000          AIX 3.2
203 **         Dec Alpha           OSF 1 ????
204 **         Intel 386           BSDI BSD/386
205 **         Intel 386           SCO OpenServer Release 5
206 **         Apollo              Domain 10.4
207 **         NEC                 SVR4
208 */
209 
210 /* On MOST systems this will get you MAXPATHLEN.
211    Windows NT doesn't have this file, tho.  */
212 #ifdef HAVE_SYS_PARAM_H
213 #include <sys/param.h>
214 #endif
215 
216 #ifndef PATH_MAX
217 #  ifdef MAXPATHLEN
218 #    define PATH_MAX                 MAXPATHLEN
219 #  else
220 #    include <limits.h>
221 #    ifndef PATH_MAX
222 #      ifdef PATHSIZE
223 #         define PATH_MAX               PATHSIZE
224 #      else /* no PATHSIZE */
225 #        ifdef _POSIX_PATH_MAX
226 #          define PATH_MAX             _POSIX_PATH_MAX
227 #        else
228 #          define PATH_MAX             1024
229 #        endif  /* no _POSIX_PATH_MAX */
230 #      endif  /* no PATHSIZE */
231 #    endif /* no PATH_MAX   */
232 #  endif  /* MAXPATHLEN */
233 #endif  /* PATH_MAX   */
234 
235 
236 /* The NeXT (without _POSIX_SOURCE, which we don't want) has a utime.h
237    which doesn't define anything.  It would be cleaner to have configure
238    check for struct utimbuf, but for now I'm checking NeXT here (so I don't
239    have to debug the configure check across all the machines).  */
240 #if defined (HAVE_UTIME_H) && !defined (NeXT)
241 #  include <utime.h>
242 #else
243 #  if defined (HAVE_SYS_UTIME_H)
244 #    include <sys/utime.h>
245 #  else
246 #    ifndef ALTOS
247 struct utimbuf
248 {
249   long actime;
250   long modtime;
251 };
252 #    endif
253 int utime ();
254 #  endif
255 #endif
256 
257 #include <string.h>
258 
259 #ifndef ERRNO_H_MISSING
260 #include <errno.h>
261 #endif
262 
263 /* Not all systems set the same error code on a non-existent-file
264    error.  This tries to ask the question somewhat portably.
265    On systems that don't have ENOTEXIST, this should behave just like
266    x == ENOENT.  "x" is probably errno, of course. */
267 
268 #ifdef ENOTEXIST
269 #  ifdef EOS2ERR
270 #    define existence_error(x) \
271      (((x) == ENOTEXIST) || ((x) == ENOENT) || ((x) == EOS2ERR))
272 #  else
273 #    define existence_error(x) \
274      (((x) == ENOTEXIST) || ((x) == ENOENT))
275 #  endif
276 #else
277 #  ifdef EVMSERR
278 #     define existence_error(x) \
279 ((x) == ENOENT || (x) == EINVAL || (x) == EVMSERR)
280 #  else
281 #    define existence_error(x) ((x) == ENOENT)
282 #  endif
283 #endif
284 
285 
286 #ifdef STDC_HEADERS
287 #include <stdlib.h>
288 #else
289 char *getenv ();
290 char *malloc ();
291 char *realloc ();
292 char *calloc ();
293 extern int errno;
294 #endif
295 
296 /* SunOS4 apparently does not define this in stdlib.h.  */
297 #ifndef EXIT_FAILURE
298 #define EXIT_FAILURE 1
299 #endif
300 
301 /* check for POSIX signals */
302 #if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK)
303 # define POSIX_SIGNALS
304 #endif
305 
306 /* MINIX 1.6 doesn't properly support sigaction */
307 #if defined(_MINIX)
308 # undef POSIX_SIGNALS
309 #endif
310 
311 /* If !POSIX, try for BSD.. Reason: 4.4BSD implements these as wrappers */
312 #if !defined(POSIX_SIGNALS)
313 # if defined(HAVE_SIGVEC) && defined(HAVE_SIGSETMASK) && defined(HAVE_SIGBLOCK)
314 #  define BSD_SIGNALS
315 # endif
316 #endif
317 
318 /* Under OS/2, this must be included _after_ stdio.h; that's why we do
319    it here. */
320 #ifdef USE_OWN_TCPIP_H
321 #include "tcpip.h"
322 #endif
323 
324 #ifdef HAVE_FCNTL_H
325 #include <fcntl.h>
326 #else
327 #include <sys/file.h>
328 #endif
329 
330 #ifndef SEEK_SET
331 #define SEEK_SET 0
332 #define SEEK_CUR 1
333 #define SEEK_END 2
334 #endif
335 
336 #ifndef F_OK
337 #define F_OK 0
338 #define X_OK 1
339 #define W_OK 2
340 #define R_OK 4
341 #endif
342 
343 #if HAVE_DIRENT_H
344 # include <dirent.h>
345 # define NAMLEN(dirent) strlen((dirent)->d_name)
346 #else
347 # define dirent direct
348 # define NAMLEN(dirent) (dirent)->d_namlen
349 # if HAVE_SYS_NDIR_H
350 #  include <sys/ndir.h>
351 # endif
352 # if HAVE_SYS_DIR_H
353 #  include <sys/dir.h>
354 # endif
355 # if HAVE_NDIR_H
356 #  include <ndir.h>
357 # endif
358 #endif
359 
360 /* Convert B 512-byte blocks to kilobytes if K is nonzero,
361    otherwise return it unchanged. */
362 #define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
363 
364 #ifndef S_ISLNK
365 #define lstat stat
366 #endif
367 
368 /*
369  * Some UNIX distributions don't include these in their stat.h Defined here
370  * because "config.h" is always included last.
371  */
372 #ifndef S_IWRITE
373 #define	S_IWRITE	0000200		/* write permission, owner */
374 #endif
375 #ifndef S_IWGRP
376 #define	S_IWGRP		0000020		/* write permission, grougroup */
377 #endif
378 #ifndef S_IWOTH
379 #define	S_IWOTH		0000002		/* write permission, other */
380 #endif
381 
382 /* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem
383    calls take  only one argument; permission is handled very differently on
384    those systems than in Unix.  So we leave such systems a hook on which they
385    can hang their own definitions.  */
386 
387 #ifndef CVS_ACCESS
388 #define CVS_ACCESS access
389 #endif
390 
391 #ifndef CVS_CHDIR
392 #define CVS_CHDIR chdir
393 #endif
394 
395 #ifndef CVS_CREAT
396 #define CVS_CREAT creat
397 #endif
398 
399 #ifndef CVS_FOPEN
400 #define CVS_FOPEN fopen
401 #endif
402 
403 #ifndef CVS_FDOPEN
404 #define CVS_FDOPEN fdopen
405 #endif
406 
407 #ifndef CVS_MKDIR
408 #define CVS_MKDIR mkdir
409 #endif
410 
411 #ifndef CVS_OPEN
412 #define CVS_OPEN open
413 #endif
414 
415 #ifndef CVS_READDIR
416 #define CVS_READDIR readdir
417 #endif
418 
419 #ifndef CVS_CLOSEDIR
420 #define CVS_CLOSEDIR closedir
421 #endif
422 
423 #ifndef CVS_OPENDIR
424 #define CVS_OPENDIR opendir
425 #endif
426 
427 #ifndef CVS_RENAME
428 #define CVS_RENAME rename
429 #endif
430 
431 #ifndef CVS_RMDIR
432 #define CVS_RMDIR rmdir
433 #endif
434 
435 #ifndef CVS_STAT
436 #define CVS_STAT stat
437 #endif
438 
439 /* Open question: should CVS_STAT be lstat by default?  We need
440    to use lstat in order to handle symbolic links correctly with
441    the PreservePermissions option. -twp */
442 #ifndef CVS_LSTAT
443 #define CVS_LSTAT lstat
444 #endif
445 
446 #ifndef CVS_UNLINK
447 #define CVS_UNLINK unlink
448 #endif
449 
450 /* Wildcard matcher.  Should be case-insensitive if the system is.  */
451 #ifndef CVS_FNMATCH
452 #define CVS_FNMATCH fnmatch
453 #endif
454 
455 #if defined (__CYGWIN32__) || defined (WIN32)
456 
457 /* Under Windows NT, filenames are case-insensitive, and both / and \
458    are path component separators.  */
459 
460 #define FOLD_FN_CHAR(c) (WNT_filename_classes[(unsigned char) (c)])
461 extern unsigned char WNT_filename_classes[];
462 #define FILENAMES_CASE_INSENSITIVE 1
463 
464 /* Is the character C a path name separator?  Under
465    Windows NT, you can use either / or \.  */
466 #define ISDIRSEP(c) (FOLD_FN_CHAR(c) == '/')
467 
468 /* Like strcmp, but with the appropriate tweaks for file names.
469    Under Windows NT, filenames are case-insensitive but case-preserving,
470    and both \ and / are path element separators.  */
471 extern int fncmp (const char *n1, const char *n2);
472 
473 /* Fold characters in FILENAME to their canonical forms.
474    If FOLD_FN_CHAR is not #defined, the system provides a default
475    definition for this.  */
476 extern void fnfold (char *FILENAME);
477 
478 #endif /* defined (__CYGWIN32__) || defined (WIN32) */
479 
480 /* Some file systems are case-insensitive.  If FOLD_FN_CHAR is
481    #defined, it maps the character C onto its "canonical" form.  In a
482    case-insensitive system, it would map all alphanumeric characters
483    to lower case.  Under Windows NT, / and \ are both path component
484    separators, so FOLD_FN_CHAR would map them both to /.  */
485 #ifndef FOLD_FN_CHAR
486 #define FOLD_FN_CHAR(c) (c)
487 #define fnfold(filename) (filename)
488 #define fncmp strcmp
489 #endif
490 
491 /* Different file systems have different path component separators.
492    For the VMS port we might need to abstract further back than this.  */
493 #ifndef ISDIRSEP
494 #define ISDIRSEP(c) ((c) == '/')
495 #endif
496 
497 
498 /* On some systems, we have to be careful about writing/reading files
499    in text or binary mode (so in text mode the system can handle CRLF
500    vs. LF, VMS text file conventions, &c).  We decide to just always
501    be careful.  That way we don't have to worry about whether text and
502    binary differ on this system.  We just have to worry about whether
503    the system has O_BINARY and "rb".  The latter is easy; all ANSI C
504    libraries have it, SunOS4 has it, and CVS has used it unguarded
505    some places for a while now without complaints (e.g. "rb" in
506    server.c (server_updated), since CVS 1.8).  The former is just an
507    #ifdef.  */
508 
509 #define FOPEN_BINARY_READ ("rb")
510 #define FOPEN_BINARY_WRITE ("wb")
511 
512 #ifdef O_BINARY
513 #define OPEN_BINARY (O_BINARY)
514 #else
515 #define OPEN_BINARY (0)
516 #endif
517