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