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
155off_t lseek ();
156char *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
247struct utimbuf
248{
249  long actime;
250  long modtime;
251};
252#    endif
253int 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
289char *getenv ();
290char *malloc ();
291char *realloc ();
292char *calloc ();
293extern 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)])
461extern 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.  */
471extern 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.  */
476extern 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