1 /*
2 Copyright 2021 Northern.tech AS
3
4 This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 3.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18
19 To the extent this program is licensed as part of the Enterprise
20 versions of CFEngine, the applicable Commercial Open Source License
21 (COSL) may apply to this file if you as a licensee so wish it. See
22 included file COSL.txt.
23 */
24
25 #ifndef CFENGINE_PLATFORM_H
26 #define CFENGINE_PLATFORM_H
27
28 /*
29 * Platform-specific definitions and declarations.
30 *
31 * INCLUDE THIS HEADER ALWAYS FIRST in order to define appropriate macros for
32 * including system headers (such as _FILE_OFFSET_BITS).
33 */
34
35 #ifdef HAVE_CONFIG_H
36 # include <config.h>
37 #endif
38
39 #define _GNU_SOURCE 1
40
41 #ifdef _WIN32
42 # define MAX_FILENAME 227
43 # define WINVER 0x501
44 # if defined(__CYGWIN__)
45 # undef FD_SETSIZE
46 # endif
47 /* Increase select(2) FD limit from 64. It's documented and valid to do it
48 * like that provided that we define it *before* including winsock2.h. */
49 # define FD_SETSIZE 4096
50 #else
51 # define MAX_FILENAME 254
52 #endif
53
54 #ifdef __MINGW32__
55 # include <winsock2.h>
56 # include <windows.h>
57 # include <accctrl.h>
58 # include <aclapi.h>
59 # include <psapi.h>
60 # include <wchar.h>
61 # include <sddl.h>
62 # include <tlhelp32.h>
63 # include <iphlpapi.h>
64 # include <ws2tcpip.h>
65 # include <objbase.h> // for disphelper
66 # ifndef SHUT_RDWR // for shutdown()
67 # define SHUT_RDWR SD_BOTH
68 # endif
69 #endif
70
71 /* Standard C. */
72 #include <stdio.h>
73 #include <math.h>
74 #include <string.h>
75 #include <ctype.h>
76 #include <assert.h>
77 #include <stddef.h> /* offsetof, size_t */
78
79 /* POSIX but available in all platforms. */
80 #include <strings.h>
81 #include <limits.h>
82
83 #ifdef HAVE_SYS_SYSMACROS_H
84 # include <sys/sysmacros.h>
85 #endif
86
87 #include <sys/types.h>
88 #include <sys/stat.h>
89
90 /* We now require a pthreads implementation. */
91 #include <pthread.h>
92
93 #ifndef _GETOPT_H
94 # include <../libcompat/getopt.h>
95 #endif
96
97 #ifdef HAVE_STDLIB_H
98 # include <stdlib.h>
99 #endif
100
101 #ifdef HAVE_UNAME
102 # include <sys/utsname.h>
103 #else
104 # define _SYS_NMLN 257
105
106 struct utsname
107 {
108 char sysname[_SYS_NMLN];
109 char nodename[_SYS_NMLN];
110 char release[_SYS_NMLN];
111 char version[_SYS_NMLN];
112 char machine[_SYS_NMLN];
113 };
114
115 #endif
116
117 #ifdef HAVE_STDINT_H
118 # include <stdint.h>
119 #endif
120
121 #ifdef HAVE_INTTYPES_H
122 # include <inttypes.h>
123 #endif
124
125 #ifdef HAVE_SYS_SYSTEMINFO_H
126 # include <sys/systeminfo.h>
127 #endif
128
129 #ifdef HAVE_SYS_PARAM_H
130 # include <sys/param.h>
131 #endif
132
133 #ifdef HAVE_SYS_MOUNT_H
134 # include <sys/mount.h>
135 #endif
136
137 #ifdef HAVE_SYS_WAIT_H
138 # include <sys/wait.h>
139 #endif
140 #ifndef WEXITSTATUS
141 # define WEXITSTATUS(s) ((unsigned)(s) >> 8)
142 #endif
143 #ifndef WIFEXITED
144 # define WIFEXITED(s) (((s) & 255) == 0)
145 #endif
146 #ifndef WIFSIGNALED
147 # define WIFSIGNALED(s) ((s) & 0) /* Can't use for BSD */
148 #endif
149 #ifndef WTERMSIG
150 # define WTERMSIG(s) ((s) & 0)
151 #endif
152
153 #include <stdbool.h>
154
155 #include <errno.h>
156
157 #ifdef HAVE_DIRENT_H
158 # include <dirent.h>
159 #else
160 # define dirent direct
161 # if HAVE_SYS_NDIR_H
162 # include <sys/ndir.h>
163 # endif
164 # if HAVE_SYS_DIR_H
165 # include <sys/dir.h>
166 # endif
167 # if HAVE_NDIR_H
168 # include <ndir.h>
169 # endif
170 #endif
171
172 #ifndef PATH_MAX
173 # ifdef _MAX_PATH
174 # define PATH_MAX _MAX_PATH
175 # else
176 # define PATH_MAX 4096
177 # endif
178 #endif
179
180 #include <signal.h>
181
182 #ifdef __MINGW32__
183 # define LOG_LOCAL0 (16<<3)
184 # define LOG_LOCAL1 (17<<3)
185 # define LOG_LOCAL2 (18<<3)
186 # define LOG_LOCAL3 (19<<3)
187 # define LOG_LOCAL4 (20<<3)
188 # define LOG_LOCAL5 (21<<3)
189 # define LOG_LOCAL6 (22<<3)
190 # define LOG_LOCAL7 (23<<3)
191 # define LOG_USER (1<<3)
192 # define LOG_DAEMON (3<<3)
193
194 /* MinGW added this flag only in latest version. */
195 # ifndef IPV6_V6ONLY
196 # define IPV6_V6ONLY 27
197 # endif
198
199 // Not available in MinGW headers unless you raise WINVER and _WIN32_WINNT, but
200 // that is very badly supported in MinGW ATM.
201 ULONGLONG WINAPI GetTickCount64(void);
202
203 #else /* !__MINGW32__ */
204 # include <syslog.h>
205 #endif
206
207 #ifdef _AIX
208 # ifndef ps2
209 # include <sys/statfs.h>
210 # endif
211
212 # include <sys/systemcfg.h>
213 #endif
214
215 #ifdef __sun
216 # include <sys/statvfs.h>
217 # undef nfstype
218
219 #include <sys/mkdev.h>
220
221 #ifndef timersub
222 # define timersub(a, b, result) \
223 do \
224 { \
225 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
226 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
227 if ((result)->tv_usec < 0) \
228 { \
229 --(result)->tv_sec; \
230 (result)->tv_usec += 1000000; \
231 } \
232 } while (0)
233 #endif
234
235 #endif
236
237 #if !HAVE_DECL_DIRFD
238 int dirfd(DIR *dirp);
239 #endif
240
241 /* strndup is defined as a macro on many systems */
242 #if !HAVE_DECL_STRNDUP
243 # ifndef strndup
244 char *strndup(const char *s, size_t n);
245 # endif
246 #endif
247
248 #if !HAVE_DECL_STRNLEN
249 size_t strnlen(const char *str, size_t maxlen);
250 #endif
251
252 #ifdef HAVE_UNISTD_H
253 # include <unistd.h>
254 #endif
255
256 #if !HAVE_DECL_STRLCPY
257 size_t strlcpy(char *destination, const char *source, size_t size);
258 #endif
259
260 #if !HAVE_DECL_STRLCAT
261 size_t strlcat(char *destination, const char *source, size_t size);
262 #endif
263
264 #if !HAVE_DECL_STRSEP
265 char *strsep(char **stringp, const char *delim);
266 #endif
267
268 #if !HAVE_DECL_SOCKETPAIR
269 int socketpair(int domain, int type, int protocol, int sv[2]);
270 #endif
271
272 #if !HAVE_DECL_FSYNC
273 int fsync(int fd);
274 #endif
275
276 #if !HAVE_DECL_GLOB
277 #define GLOB_NOSPACE 1
278 #define GLOB_ABORTED 2
279 #define GLOB_NOMATCH 3
280 typedef struct {
281 size_t gl_pathc; /* Count of paths matched so far */
282 char **gl_pathv; /* List of matched pathnames. */
283 size_t gl_offs;
284 } glob_t;
285 int glob(const char *pattern,
286 int flags,
287 int (*errfunc) (const char *epath, int eerrno),
288 glob_t *pglob);
289 void globfree(glob_t *pglob);
290 #endif
291
292 #ifdef __APPLE__
293 # include <sys/malloc.h>
294 # include <sys/paths.h>
295 #endif
296
297 #ifdef HAVE_SYS_MALLOC_H
298 # ifdef __APPLE__
299 # include <sys/malloc.h>
300 # include <sys/paths.h>
301 # endif
302 #else
303 # ifdef HAVE_MALLOC_H
304 # ifndef __OpenBSD__
305 # ifdef __FreeBSD__
306 # include <stdlib.h>
307 # else
308 # include <malloc.h>
309 # endif
310 # endif
311 # endif
312 #endif
313
314 #include <fcntl.h>
315
316 #ifdef HAVE_VFS_H
317 # include <sys/vfs.h>
318 #endif
319
320 #ifdef __hpux
321 # include <sys/dirent.h>
322 #endif
323
324 #ifdef HAVE_UTIME_H
325 # include <utime.h> /* use utime not utimes for portability */
326 #elif TIME_WITH_SYS_TIME
327 # include <sys/time.h>
328 # include <time.h>
329 #elif HAVE_SYS_TIME_H
330 # include <sys/time.h>
331 #elif ! defined(AOS)
332 # include <time.h>
333 #endif
334
335 #ifdef HAVE_TIME_H
336 # include <time.h>
337 #endif
338
339 #ifdef HAVE_SYS_TIME_H
340 # include <sys/time.h>
341 #endif
342
343 #ifdef HAVE_SYS_RESOURCE_H
344 # include <sys/resource.h>
345 #endif
346
347 #ifndef __MINGW32__
348 # include <pwd.h>
349 # include <grp.h>
350 #endif
351
352 #ifdef HAVE_SYS_SOCKIO_H
353 # include <sys/sockio.h>
354 #endif
355
356 /*
357 Work around bug in HPUX system headers:
358 "/usr/include/machine/sys/getppdp.h:65: error: array type has incomplete element type"
359 */
360 #ifdef __hpux
361 union mpinfou
362 {
363 int dummy;
364 };
365 #endif
366
367 #ifndef __MINGW32__
368 # include <sys/socket.h>
369 # include <sys/ioctl.h>
370 # include <net/if.h>
371 # include <netinet/in.h>
372 # include <netinet/in_systm.h>
373 # include <netinet/ip.h>
374 # include <netinet/tcp.h>
375 # include <arpa/inet.h>
376 # include <netdb.h>
377 # if !defined __linux__ && !defined _WIN32
378 # include <sys/protosw.h>
379 # undef sgi
380 # include <net/route.h>
381 # endif
382 #endif
383
384 #ifdef __linux__
385 # ifdef HAVE_NET_ROUTE_H
386 # include <net/route.h>
387 # else
388 # include <linux/route.h>
389 # endif
390
391 # ifdef HAVE_NETINET_IN_H
392 # include <netinet/in.h>
393 # else
394 # include <linux/in.h>
395 # endif
396
397 # ifdef HAVE_NETINET_IP_H
398 # include <netinet/ip.h>
399 # else
400 # include <linux/ip.h>
401 # endif
402 #endif
403
404 #ifdef __linux__
405 #define ARG_LINUX_ONLY
406 #else
407 #define ARG_LINUX_ONLY ARG_UNUSED
408 #endif
409
410 #ifndef CLOCK_REALTIME
411 # define CLOCK_REALTIME 1
412 #endif
413
414 #ifndef HAVE_CLOCKID_T
415 typedef int clockid_t;
416 #endif
417
418 #ifndef HAVE_SOCKLEN_T
419 typedef int socklen_t;
420 #endif
421
422 # ifndef _SC_THREAD_STACK_MIN
423 # define _SC_THREAD_STACK_MIN PTHREAD_STACK_MIN
424 #endif
425
426 #ifndef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
427 # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_MUTEX_INITIALIZER
428 #endif
429
430 #if !HAVE_DECL_GETLOADAVG
431 int getloadavg (double loadavg[], int nelem);
432 #endif
433
434 #ifdef HAVE_ENDIAN_H
435 # include <endian.h>
436 #endif
437
438 #if !HAVE_DECL_LE32TOH
ByteSwap32(uint32_t le32uint)439 static inline uint32_t ByteSwap32(uint32_t le32uint)
440 {
441 uint32_t be32uint;
442 unsigned char *le_ptr = (unsigned char *)&le32uint;
443 unsigned char *be_ptr = (unsigned char *)&be32uint;
444 be_ptr[0] = le_ptr[3];
445 be_ptr[1] = le_ptr[2];
446 be_ptr[2] = le_ptr[1];
447 be_ptr[3] = le_ptr[0];
448 return be32uint;
449 }
450 # ifdef WORDS_BIGENDIAN
451 # ifndef le32toh
452 # define le32toh(x) ByteSwap32(x)
453 # endif
454 # ifndef htole32
455 # define htole32(x) ByteSwap32(x)
456 # endif
457 # else
458 # ifndef le32toh
459 # define le32toh(x) (x)
460 # endif
461 # ifndef htole32
462 # define htole32(x) (x)
463 # endif
464 # endif
465 #endif // !HAVE_DECL_LE32TOH
466
467 #if !HAVE_DECL_CLOSEFROM
468 int closefrom(int fd);
469 #endif
470
471 #if !HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE
472 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
473 #endif
474
475 #ifdef HAVE_SCHED_H
476 # include <sched.h>
477 #endif
478
479 #if defined(HAVE_SYS_XATTR_H)
480 # include <sys/xattr.h>
481 #elif defined(HAVE_ATTR_XATTR_H)
482 # include <attr/xattr.h>
483 #endif
484
485 #ifndef MIN
486 # define MIN(a, b) ((a) < (b) ? (a) : (b))
487 #endif
488
489 #ifndef MAX
490 # define MAX(a, b) ((a) > (b) ? (a) : (b))
491 #endif
492
493 #ifndef INADDR_NONE
494 # define INADDR_NONE ((unsigned long int) 0xffffffff)
495 #endif
496 #ifndef HAVE_SETEGID
497 int setegid(gid_t gid);
498 #endif
499 #if !HAVE_DECL_UNAME
500 int uname(struct utsname *buf);
501 #endif
502 #if !HAVE_DECL_GETUID
503 uid_t getuid(void);
504 #endif
505 #if !HAVE_DECL_GETGID
506 gid_t getgid(void);
507 #endif
508 #if !HAVE_DECL_FGETGRENT
509 struct group *fgetgrent(FILE *stream);
510 #endif
511 #if !HAVE_DECL_DRAND48
512 double drand48(void);
513 #endif
514 #if !HAVE_DECL_SRAND48
515 void srand48(long seed);
516 #endif
517 #if !HAVE_DECL_CLOCK_GETTIME
518 int clock_gettime(clockid_t clock_id, struct timespec *tp);
519 #endif
520
521 #if !HAVE_DECL_REALPATH
522 /**
523 * WARNING realpath() has varying behaviour among platforms.
524 * - Do not use it to convert relative paths to absolute
525 * (Solaris under certain conditions will return relative path).
526 * - Do not use it to check existence of file
527 * (on *BSD the last component of the path may not exist).
528 * Use it only to resolve all symlinks and canonicalise filename,
529 * i.e. remove double '/' and "/./" and "/../".
530 *
531 * @TODO what we need is a resolvepath(2) cross-platform implementation.
532 */
533 # if defined (__MINGW32__)
534 # define realpath(N,R) _fullpath((R), (N), PATH_MAX)
535 # endif
536 #endif
537
538 #if !HAVE_DECL_LSTAT
539 int lstat(const char *file_name, struct stat *buf);
540 #endif
541 #if !HAVE_DECL_SLEEP
542 unsigned int sleep(unsigned int seconds);
543 #endif
544 #if !HAVE_DECL_ROUND
545 double round(double x);
546 #endif
547 #if !HAVE_DECL_NANOSLEEP
548 int nanosleep(const struct timespec *req, struct timespec *rem);
549 #endif
550 #if !HAVE_DECL_CHOWN
551 int chown(const char *path, uid_t owner, gid_t group);
552 #endif
553 #if !HAVE_DECL_FCHMOD
554 int fchmod(int fd, mode_t mode);
555 #endif
556
557 #if !HAVE_DECL_GETNETGRENT
558 int getnetgrent(char **host, char **user, char **domain);
559 #endif
560
561 #if !HAVE_DECL_SETNETGRENT
562 #if SETNETGRENT_RETURNS_INT
563 int setnetgrent(const char *netgroup);
564 #else
565 void setnetgrent(const char *netgroup);
566 #endif
567 #endif
568
569 #if !HAVE_DECL_ENDNETGRENT
570 #if ENDNETGRENT_RETURNS_INT
571 int endnetgrent(void);
572 #else
573 void endnetgrent(void);
574 #endif
575 #endif
576
577 #if !HAVE_DECL_STRSTR
578 char *strstr(const char *haystack, const char *needle);
579 #endif
580 #if !HAVE_DECL_STRCASESTR
581 char *strcasestr(const char *haystack, const char *needle);
582 #endif
583 #if !HAVE_DECL_STRCASECMP
584 int strcasecmp(const char *s1, const char *s2);
585 #endif
586 #if !HAVE_DECL_STRNCASECMP
587 int strncasecmp(const char *s1, const char *s2, size_t n);
588 #endif
589 #if !HAVE_DECL_STRSIGNAL
590 char *strsignal(int sig);
591 #endif
592 #if !HAVE_DECL_STRDUP
593 char *strdup(const char *str);
594 #endif
595 #if !HAVE_DECL_MEMRCHR
596 void *memrchr(const void *s, int c, size_t n);
597 #endif
598 #if !HAVE_DECL_MEMDUP
599 void *memdup(const void *mem, size_t size);
600 #endif
601 #if !HAVE_DECL_MEMMEM
602 void *memmem(const void *haystack, size_t haystacklen,
603 const void *needle, size_t needlelen);
604 #endif
605 #if !HAVE_DECL_STRERROR
606 char *strerror(int err);
607 #endif
608 #if !HAVE_DECL_UNSETENV
609 int unsetenv(const char *name);
610 #endif
611 #ifndef HAVE_SETEUID
612 int seteuid(uid_t euid);
613 #endif
614 #ifndef HAVE_SETEUID
615 int setegid(gid_t egid);
616 #endif
617 #if !HAVE_DECL_SETLINEBUF
618 void setlinebuf(FILE *stream);
619 #endif
620
621 #if HAVE_STDARG_H
622 # include <stdarg.h>
623 # if !HAVE_VSNPRINTF
624 int rpl_vsnprintf(char *, size_t, const char *, va_list);
625 /* If [v]snprintf() does not exist or is not C99 compatible, then we assume
626 * that [v]printf() and [v]fprintf() need to be provided as well. */
627 int rpl_vprintf(const char *format, va_list ap);
628 int rpl_vfprintf(FILE *stream, const char *format, va_list ap);
629 # endif
630 # if !HAVE_SNPRINTF
631 int rpl_snprintf(char *, size_t, const char *, ...);
632 int rpl_printf(const char *format, ...);
633 int rpl_fprintf(FILE *stream, const char *format, ...);
634 # endif
635 # if !HAVE_VASPRINTF
636 int rpl_vasprintf(char **, const char *, va_list);
637 # endif
638 # if !HAVE_ASPRINTF
639 int rpl_asprintf(char **, const char *, ...);
640 # endif
641 #endif /* HAVE_STDARG_H */
642
643 /* For example Solaris, does not have isfinite() in <math.h>. */
644 #if !HAVE_DECL_ISFINITE && defined(HAVE_IEEEFP_H)
645 # include <ieeefp.h>
646 # define isfinite(x) finite(x)
647 #endif
648
649 #if !HAVE_DECL_GETLINE
650 ssize_t getline(char **lineptr, size_t *n, FILE *stream);
651 #endif
652 #if !HAVE_DECL_STRCHRNUL
653 char *strchrnul(const char *s, int c);
654 #endif
655 #if !HAVE_DECL_GMTIME_R
656 struct tm *gmtime_r(const time_t *timep, struct tm *result);
657 #endif
658 #if !HAVE_DECL_LOCALTIME_R
659 struct tm *localtime_r(const time_t *timep, struct tm *result);
660 #endif
661 #if !HAVE_DECL_CHMOD
662 int chmod(const char *path, mode_t mode);
663 #endif
664 #if !HAVE_DECL_ALARM
665 unsigned int alarm(unsigned int seconds);
666 #endif
667 #if !HAVE_DECL_MKDTEMP
668 char *mkdtemp(char *template);
669 #endif
670 #if !HAVE_DECL_STRRSTR
671 char *strrstr(const char *haystack, const char *needle);
672 #endif
673 #if !HAVE_DECL_STPNCPY
674 char *stpncpy(char *dst, const char *src, size_t len);
675 #endif
676 #if !HAVE_DECL_INET_NTOP
677 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
678 #endif
679 #if !HAVE_DECL_INET_PTON
680 int inet_pton(int af, const char *src, void *dst);
681 #endif
682 #if !HAVE_DECL_GETADDRINFO
683 int getaddrinfo(const char *node, const char *service,
684 const struct addrinfo *hints, struct addrinfo **res);
685 void freeaddrinfo(struct addrinfo *res);
686 int getnameinfo(const struct sockaddr *sa, socklen_t salen,
687 char *node, socklen_t nodelen,
688 char *service, socklen_t servicelen, int flags);
689 const char *gai_strerror(int errcode);
690 #endif
691 #if !HAVE_STRUCT_SOCKADDR_STORAGE
692 #ifdef AF_INET6
693 #define sockaddr_storage sockaddr_in6
694 #else
695 #define sockaddr_storage sockaddr
696 #endif
697 #endif
698 #ifndef AF_INET6
699 /* if the platform doesn't have it, it's useless, but define it as -1
700 * since we need it in our code... */
701 #define AF_INET6 -1
702 #endif
703 #ifndef AI_NUMERICSERV
704 /* Not portable to MinGW so don't use it. */
705 #define AI_NUMERICSERV -1
706 #endif
707
708 #if !defined(HAVE_MKDIR_PROPER)
709 int rpl_mkdir(const char *pathname, mode_t mode);
710 #endif
711
712 #if !defined(HAVE_STAT_PROPER)
713 int rpl_stat(const char *path, struct stat *buf);
714 #define _stat64(name, st) rpl_stat(name, st)
715 #endif
716
717 #if !defined(HAVE_RENAME_PROPER)
718 int rpl_rename(const char *oldpath, const char *newpath);
719 #endif
720
721 #if !defined(HAVE_CTIME_PROPER)
722 char *rpl_ctime(const time_t *t);
723 #endif
724
725 #ifndef NGROUPS
726 # define NGROUPS 20
727 #endif
728
729 #if !HAVE_DECL_OPENAT
730 int openat(int dirfd, const char *pathname, int flags, ...);
731 #endif
732 #if !HAVE_DECL_FSTATAT
733 int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags);
734 #endif
735 #if !HAVE_DECL_FCHOWNAT
736 int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags);
737 #endif
738 #if !HAVE_DECL_FCHMODAT
739 int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
740 #endif
741 #if !HAVE_DECL_READLINKAT
742 int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz);
743 #endif
744 #ifndef AT_SYMLINK_NOFOLLOW
745 #define AT_SYMLINK_NOFOLLOW 0x1000
746 #endif
747 #ifndef AT_FDCWD
748 #define AT_FDCWD (-2)
749 #endif
750
751 #if !HAVE_DECL_LOG2
752 double log2(double x);
753 #endif
754
755 /*******************************************************************/
756 /* Windows */
757 /*******************************************************************/
758
759 #ifdef __MINGW32__
760 # define MAXHOSTNAMELEN 256 // always adequate: http://msdn.microsoft.com/en-us/library/ms738527(VS.85).aspx
761
762 // as seen in in_addr struct in winsock.h
763 typedef u_long in_addr_t;
764
765 // shold be in winnt.h, but is not in current MinGW version
766 # ifndef VER_SUITE_WH_SERVER
767 # define VER_SUITE_WH_SERVER 0x00008000
768 # endif
769
770 /* Dummy signals, can be set to anything below 23 but
771 * 2, 4, 8, 11, 15, 21, 22 which are taken.
772 * Calling signal() with anything from below causes SIG_ERR
773 * to be returned. */
774
775 # define SIGALRM 1
776 # define SIGHUP 3
777 # define SIGTRAP 5
778 # define SIGKILL 6
779 # define SIGPIPE 7
780 # define SIGCONT 9
781 # define SIGSTOP 10
782 # define SIGQUIT 12
783 # define SIGCHLD 13
784 # define SIGUSR1 14
785 # define SIGUSR2 16
786 # define SIGBUS 17
787
788 # if !defined( _TIMESPEC_DEFINED) && !defined(HAVE_STRUCT_TIMESPEC)
789 # define HAVE_STRUCT_TIMESPEC 1
790 struct timespec
791 {
792 long tv_sec;
793 long tv_nsec;
794 };
795 # endif/* NOT _TIMESPEC_DEFINED */
796
797 #endif /* __MINGW32__ */
798
799 #ifndef ERESTARTSYS
800 # define ERESTARTSYS EINTR
801 #endif
802
803 #ifndef EOPNOTSUPP
804 # define EOPNOTSUPP EINVAL
805 #endif
806
807 #ifndef ENOTSUPP
808 # define ENOTSUPP EINVAL
809 #endif
810
811 #ifndef ENOLINK
812 // Should be well outside the range of any errno value.
813 // Will never actually be returned by any function on a platform that doesn't support it.
814 # define ENOLINK 123456
815 #endif
816
817 /*******************************************************************/
818 /* Copy file defines */
819 /*******************************************************************/
820
821 /**
822 * DEV_BSIZE is 512 for most common platforms
823 * (Linux, AIX on Power, Solaris etc).
824 *
825 * Exceptions:
826 * HP-UX: 1024
827 * AIX on PS/2: 4096
828 * Windows: undefined
829 */
830 #ifndef DEV_BSIZE /* usually defined in <sys/param.h> */
831 # ifdef BSIZE
832 # define DEV_BSIZE BSIZE
833 # else
834 # define DEV_BSIZE 512
835 # endif
836 #endif
837
838 /**
839 Extract or fake data from a `struct stat'.
840 ST_BLKSIZE: Optimal I/O blocksize for the file, in bytes.
841 This is tightly coupled to ST_NBLOCKS, i.e it must stand that
842 (s.st_size <= ST_NBLOCKS(s) * ST_BLKSIZE(s))
843 ST_NBLOCKS: Number of blocks in the file, **in ST_BLKSIZE units**
844 WARNING this is different than "stat.st_nblocks" on most systems
845 ST_NBYTES : "disk usage" of the file on the disk, **in bytes**.
846
847 TODO on Windows here is how to get the "cluster size" i.e. the block size:
848 - send IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and use Geometry.BytesPerSector
849 from DISK_GEOMETRY_EX structure
850 - To check if a file is sparse: File.GetAttributes().SparseFile
851 */
852
853 /*
854 * Known platforms that don't have stat.st_blocks:
855 * Windows (MinGW)
856 */
857 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
858
859
860 # define ST_BLKSIZE(statbuf) DEV_BSIZE
861 # define ST_NBLOCKS(statbuf) (((statbuf).st_size + DEV_BSIZE - 1) / DEV_BSIZE)
862 # define ST_NBYTES(statbuf) (ST_NBLOCKS(statbuf) * DEV_BSIZE)
863
864
865 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
866 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
867 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
868 ? (statbuf).st_blksize : DEV_BSIZE)
869 # define ST_NBLOCKS(statbuf) ((ST_NBYTES(statbuf) + ST_BLKSIZE(statbuf) - 1) \
870 / ST_BLKSIZE(statbuf))
871
872 # if defined(_CRAY)
873 # define ST_NBYTES(statbuf) ((statbuf).st_blocks * ST_BLKSIZE(statbuf))
874 # else
875 /* ======= DEFAULT ============================== */
876 /* Most OS give stat.st_blocks in DEV_BSIZE units */
877 # define ST_NBYTES(statbuf) ((statbuf).st_blocks * DEV_BSIZE)
878 /* ============================================== */
879 # endif /* CRAY */
880
881
882 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
883
884
885 #ifndef SEEK_CUR
886 # define SEEK_CUR 1
887 #endif
888
889 /*******************************************************************/
890 /* Ultrix/BSD don't have all these from sys/stat.h */
891 /*******************************************************************/
892
893 #ifndef S_IFBLK
894 # define S_IFBLK 0060000
895 #endif
896 #ifndef S_IFCHR
897 # define S_IFCHR 0020000
898 #endif
899 #ifndef S_IFDIR
900 # define S_IFDIR 0040000
901 #endif
902 #ifndef S_IFIFO
903 # define S_IFIFO 0010000
904 #endif
905 #ifndef S_IFREG
906 # define S_IFREG 0100000
907 #endif
908 #ifndef S_IFLNK
909 # define S_IFLNK 0120000
910 #endif
911 #ifndef S_IFSOCK
912 # define S_IFSOCK 0140000
913 #endif
914 #ifndef S_IFMT
915 # define S_IFMT 00170000
916 #endif
917
918 #ifndef S_ISREG
919 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
920 #endif
921 #ifndef S_ISDIR
922 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
923 #endif
924 #ifndef S_ISLNK
925 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
926 #endif
927 #ifndef S_ISFIFO
928 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
929 #endif
930 #ifndef S_ISCHR
931 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
932 #endif
933 #ifndef S_ISBLK
934 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
935 #endif
936 #ifndef S_ISSOCK
937 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
938 #endif
939
940 #ifndef S_IRUSR
941 # define S_IRWXU 00700
942 # define S_IRUSR 00400
943 # define S_IWUSR 00200
944 # define S_IXUSR 00100
945 #endif
946
947 #ifndef S_IRGRP
948 # define S_IRWXG 00070
949 # define S_IRGRP 00040
950 # define S_IWGRP 00020
951 # define S_IXGRP 00010
952 #endif
953
954 #ifndef S_IROTH
955 # define S_IRWXO 00007
956 # define S_IROTH 00004
957 # define S_IWOTH 00002
958 # define S_IXOTH 00001
959 #endif
960
961 /* kill(2) on OS X returns ETIMEDOUT instead of ESRCH */
962 #ifndef ETIMEDOUT
963 # define ETIMEDOUT ESRCH
964 #endif
965
966 /* For getnameinfo(). */
967 #ifndef NI_MAXHOST
968 # define NI_MAXHOST 1025
969 #endif
970
971 /********************************************************************/
972 /* *BSD chflags stuff - */
973 /********************************************************************/
974
975 #if !defined UF_NODUMP
976 # define UF_NODUMP 0
977 #endif
978 #if !defined UF_IMMUTABLE
979 # define UF_IMMUTABLE 0
980 #endif
981 #if !defined UF_APPEND
982 # define UF_APPEND 0
983 #endif
984 #if !defined UF_OPAQUE
985 # define UF_OPAQUE 0
986 #endif
987 #if !defined UF_NOUNLINK
988 # define UF_NOUNLINK 0
989 #endif
990 #if !defined SF_ARCHIVED
991 # define SF_ARCHIVED 0
992 #endif
993 #if !defined SF_IMMUTABLE
994 # define SF_IMMUTABLE 0
995 #endif
996 #if !defined SF_APPEND
997 # define SF_APPEND 0
998 #endif
999 #if !defined SF_NOUNLINK
1000 # define SF_NOUNLINK 0
1001 #endif
1002 #define CHFLAGS_MASK ( UF_NODUMP | UF_IMMUTABLE | UF_APPEND | UF_OPAQUE | UF_NOUNLINK | SF_ARCHIVED | SF_IMMUTABLE | SF_APPEND | SF_NOUNLINK )
1003
1004 /* For cygwin32 */
1005
1006 #if !defined O_BINARY
1007 # define O_BINARY 0
1008 #endif
1009
1010 #if !defined O_TEXT
1011 # define O_TEXT 0
1012 #endif
1013
1014 #if defined(__MINGW32__)
1015 /* _mkdir(3) */
1016 # include <direct.h>
1017 #endif
1018
1019
1020 /* Some shorthands. */
1021
1022 # if defined(__sun) && !defined(sun)
1023 # define sun
1024 # endif
1025
1026 # if defined(__SVR4) && !defined(SVR4)
1027 # define SVR4
1028 # endif
1029
1030 # if (defined(sun) && defined(SVR4)) || defined (SOLARIS2)
1031 # define SUNOS_5
1032 # endif
1033
1034 #include <condition_macros.h>
1035
1036 /* Must be always the last one! */
1037 #include <deprecated.h>
1038 #include <config.post.h>
1039
1040
1041 #endif /* CFENGINE_PLATFORM_H */
1042