1/*
2 * Copyright (c) 1996, 1998-2005, 2008-2010
3 *	Todd C. Miller <Todd.Miller@courtesan.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * Sponsored in part by the Defense Advanced Research Projects
18 * Agency (DARPA) and Air Force Research Laboratory, Air Force
19 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
20 */
21
22#ifndef _SUDO_MISSING_H
23#define _SUDO_MISSING_H
24
25#include <stdio.h>
26#ifdef __STDC__
27# include <stdarg.h>
28#else
29# include <varargs.h>
30#endif
31
32/*
33 * Macros that may be missing on some Operating Systems
34 */
35
36/* Deal with ANSI stuff reasonably.  */
37#ifndef  __P
38# if defined (__cplusplus) || defined (__STDC__)
39#  define __P(args)		args
40# else
41#  define __P(args)		()
42# endif
43#endif /* __P */
44
45/* Define away __attribute__ for non-gcc or old gcc */
46#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 5
47# define __attribute__(x)
48#endif
49
50/* For catching format string mismatches */
51#ifndef __printflike
52# if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7)
53#  define __printflike(f, v) 	__attribute__((__format__ (__printf__, f, v)))
54# else
55#  define __printflike(f, v)
56# endif
57#endif
58
59/*
60 * Some systems lack full limit definitions.
61 */
62#ifndef OPEN_MAX
63# define OPEN_MAX	256
64#endif
65
66#ifndef INT_MAX
67# define INT_MAX	0x7fffffff
68#endif
69
70#ifndef PATH_MAX
71# ifdef MAXPATHLEN
72#  define PATH_MAX		MAXPATHLEN
73# else
74#  ifdef _POSIX_PATH_MAX
75#   define PATH_MAX		_POSIX_PATH_MAX
76#  else
77#   define PATH_MAX		1024
78#  endif
79# endif
80#endif
81
82#ifndef MAXHOSTNAMELEN
83# define MAXHOSTNAMELEN		64
84#endif
85
86/*
87 * Posix versions for those without...
88 */
89#ifndef _S_IFMT
90# define _S_IFMT		S_IFMT
91#endif /* _S_IFMT */
92#ifndef _S_IFREG
93# define _S_IFREG		S_IFREG
94#endif /* _S_IFREG */
95#ifndef _S_IFDIR
96# define _S_IFDIR		S_IFDIR
97#endif /* _S_IFDIR */
98#ifndef _S_IFLNK
99# define _S_IFLNK		S_IFLNK
100#endif /* _S_IFLNK */
101#ifndef S_ISREG
102# define S_ISREG(m)		(((m) & _S_IFMT) == _S_IFREG)
103#endif /* S_ISREG */
104#ifndef S_ISDIR
105# define S_ISDIR(m)		(((m) & _S_IFMT) == _S_IFDIR)
106#endif /* S_ISDIR */
107
108/*
109 * Some OS's may not have this.
110 */
111#ifndef S_IRWXU
112# define S_IRWXU		0000700		/* rwx for owner */
113#endif /* S_IRWXU */
114
115/*
116 * These should be defined in <unistd.h> but not everyone has them.
117 */
118#ifndef STDIN_FILENO
119# define	STDIN_FILENO	0
120#endif
121#ifndef STDOUT_FILENO
122# define	STDOUT_FILENO	1
123#endif
124#ifndef STDERR_FILENO
125# define	STDERR_FILENO	2
126#endif
127
128/*
129 * These should be defined in <unistd.h> but not everyone has them.
130 */
131#ifndef SEEK_SET
132# define	SEEK_SET	0
133#endif
134#ifndef SEEK_CUR
135# define	SEEK_CUR	1
136#endif
137#ifndef SEEK_END
138# define	SEEK_END	2
139#endif
140
141/*
142 * BSD defines these in <sys/param.h> but others may not.
143 */
144#ifndef MIN
145# define MIN(a,b) (((a)<(b))?(a):(b))
146#endif
147#ifndef MAX
148# define MAX(a,b) (((a)>(b))?(a):(b))
149#endif
150
151/*
152 * Older systems may be missing stddef.h and/or offsetof macro
153 */
154#ifndef offsetof
155# ifdef __offsetof
156#  define offsetof(type, field) __offsetof(type, field)
157# else
158#  define offsetof(type, field) ((size_t)(&((type *)0)->field))
159# endif
160#endif
161
162/*
163 * Simple isblank() macro and function for systems without it.
164 */
165#ifndef HAVE_ISBLANK
166int isblank __P((int));
167# define isblank(_x)	((_x) == ' ' || (_x) == '\t')
168#endif
169
170/*
171 * Old BSD systems lack strchr(), strrchr(), memset() and memcpy()
172 */
173#if !defined(HAVE_STRCHR) && !defined(strchr)
174# define strchr(_s, _c)	index(_s, _c)
175#endif
176#if !defined(HAVE_STRRCHR) && !defined(strrchr)
177# define strrchr(_s, _c)	rindex(_s, _c)
178#endif
179#if !defined(HAVE_MEMCPY) && !defined(memcpy)
180# define memcpy(_d, _s, _n)	(bcopy(_s, _d, _n))
181#endif
182#if !defined(HAVE_MEMSET) && !defined(memset)
183# define memset(_s, _x, _n)	(bzero(_s, _n))
184#endif
185
186/*
187 * NCR's SVr4 has _innetgr(3) instead of innetgr(3) for some reason.
188 */
189#ifdef HAVE__INNETGR
190# define innetgr(n, h, u, d)	(_innetgr(n, h, u, d))
191# define HAVE_INNETGR 1
192#endif /* HAVE__INNETGR */
193
194/*
195 * On POSIX systems, O_NOCTTY is the default so some OS's may lack this define.
196 */
197#ifndef O_NOCTTY
198# define O_NOCTTY	0
199#endif /* O_NOCTTY */
200
201/*
202 * Emulate POSIX signals via sigvec(2)
203 */
204#ifndef HAVE_SIGACTION
205# define SA_ONSTACK	SV_ONSTACK
206# define SA_RESTART	SV_INTERRUPT		/* opposite effect */
207# define SA_RESETHAND	SV_RESETHAND
208# define sa_handler	sv_handler
209# define sa_mask	sv_mask
210# define sa_flags	sv_flags
211typedef struct sigvec sigaction_t;
212typedef int sigset_t;
213int sigaction __P((int sig, const sigaction_t *act, sigaction_t *oact));
214int sigemptyset __P((sigset_t *));
215int sigfillset __P((sigset_t *));
216int sigaddset __P((sigset_t *, int));
217int sigdelset __P((sigset_t *, int));
218int sigismember __P((sigset_t *, int));
219int sigprocmask __P((int, const sigset_t *, sigset_t *));
220#endif
221
222/*
223 * Extra sugar for POSIX signals to deal with the above emulation
224 * as well as the fact that SunOS has a SA_INTERRUPT flag.
225 */
226#ifdef HAVE_SIGACTION
227# ifndef HAVE_SIGACTION_T
228typedef struct sigaction sigaction_t;
229# endif
230# ifndef SA_INTERRUPT
231#  define SA_INTERRUPT	0
232# endif
233# ifndef SA_RESTART
234#  define SA_RESTART	0
235# endif
236#endif
237
238/*
239 * If dirfd() does not exists, hopefully dd_fd does.
240 */
241#if !defined(HAVE_DIRFD) && defined(HAVE_DD_FD)
242# define dirfd(_d)	((_d)->dd_fd)
243# define HAVE_DIRFD
244#endif
245
246/*
247 * Define futimes() in terms of futimesat() if needed.
248 */
249#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
250# define futimes(_f, _tv)	futimesat(_f, NULL, _tv)
251# define HAVE_FUTIMES
252#endif
253
254#if !defined(HAVE_KILLPG) && !defined(killpg)
255# define killpg(s)	kill(-(s))
256#endif
257
258/*
259 * If we lack getprogname(), emulate with __progname if possible.
260 * Otherwise, add a prototype for use with our own getprogname.c.
261 */
262#ifndef HAVE_GETPROGNAME
263# ifdef HAVE___PROGNAME
264extern const char *__progname;
265#  define getprogname()          (__progname)
266# else
267const char *getprogname __P((void));
268#endif /* HAVE___PROGNAME */
269#endif /* !HAVE_GETPROGNAME */
270
271/*
272 * Declare errno if errno.h doesn't do it for us.
273 */
274#if defined(HAVE_DECL_ERRNO) && !HAVE_DECL_ERRNO
275extern int errno;
276#endif /* !HAVE_DECL_ERRNO */
277
278#ifndef timevalclear
279# define timevalclear(tv)	((tv)->tv_sec = (tv)->tv_usec = 0)
280#endif
281#ifndef timevalisset
282# define timevalisset(tv)	((tv)->tv_sec || (tv)->tv_usec)
283#endif
284#ifndef timevalcmp
285# define timevalcmp(tv1, tv2, op)					       \
286    (((tv1)->tv_sec == (tv2)->tv_sec) ?					       \
287	((tv1)->tv_usec op (tv2)->tv_usec) :				       \
288	((tv1)->tv_sec op (tv2)->tv_sec))
289#endif
290#ifndef timevaladd
291# define timevaladd(tv1, tv2)						       \
292    do {								       \
293	(tv1)->tv_sec += (tv2)->tv_sec;					       \
294	(tv1)->tv_usec += (tv2)->tv_usec;				       \
295	if ((tv1)->tv_usec >= 1000000) {				       \
296	    (tv1)->tv_sec++;						       \
297	    (tv1)->tv_usec -= 1000000;					       \
298	}								       \
299    } while (0)
300#endif
301#ifndef timevalsub
302# define timevalsub(tv1, tv2)						       \
303    do {								       \
304	(tv1)->tv_sec -= (tv2)->tv_sec;					       \
305	(tv1)->tv_usec -= (tv2)->tv_usec;				       \
306	if ((tv1)->tv_usec < 0) {					       \
307	    (tv1)->tv_sec--;						       \
308	    (tv1)->tv_usec += 1000000;					       \
309	}								       \
310    } while (0)
311#endif
312
313/* Not all systems define NSIG in signal.h */
314#if !defined(NSIG)
315# if defined(_NSIG)
316#  define NSIG _NSIG
317# elif defined(__NSIG)
318#  define NSIG __NSIG
319# else
320#  define NSIG 64
321# endif
322#endif
323
324#ifndef WCOREDUMP
325# define WCOREDUMP(x)	((x) & 0x80)
326#endif
327
328/*
329 * HP-UX does not declare innetgr() or getdomainname().
330 * Solaris does not declare getdomainname().
331 */
332#if defined(__hpux)
333int innetgr __P((const char *, const char *, const char *, const char *));
334#endif
335#if defined(__hpux) || defined(__sun)
336int getdomainname __P((char *, size_t));
337#endif
338
339/* Functions "missing" from libc. */
340
341struct timeval;
342struct timespec;
343
344#ifndef HAVE_CLOSEFROM
345void closefrom		__P((int));
346#endif
347#ifndef HAVE_GETCWD
348char *getcwd		__P((char *, size_t size));
349#endif
350#ifndef HAVE_GETLINE
351ssize_t getline		__P((char **, size_t *, FILE *));
352#endif
353#ifndef HAVE_UTIMES
354int utimes		__P((const char *, const struct timeval *));
355#endif
356#ifdef HAVE_FUTIME
357int futimes		__P((int, const struct timeval *));
358#endif
359#ifndef HAVE_SNPRINTF
360int snprintf		__P((char *, size_t, const char *, ...))
361			    __printflike(3, 4);
362#endif
363#ifndef HAVE_VSNPRINTF
364int vsnprintf		__P((char *, size_t, const char *, va_list))
365			    __printflike(3, 0);
366#endif
367#ifndef HAVE_ASPRINTF
368int asprintf		__P((char **, const char *, ...))
369			    __printflike(2, 3);
370#endif
371#ifndef HAVE_VASPRINTF
372int vasprintf		__P((char **, const char *, va_list))
373			    __printflike(2, 0);
374#endif
375#ifndef HAVE_STRCASECMP
376int strcasecmp		__P((const char *, const char *));
377#endif
378#ifndef HAVE_STRLCAT
379size_t strlcat		__P((char *, const char *, size_t));
380#endif
381#ifndef HAVE_STRLCPY
382size_t strlcpy		__P((char *, const char *, size_t));
383#endif
384#ifndef HAVE_MEMRCHR
385void *memrchr		__P((const void *, int, size_t));
386#endif
387#ifndef HAVE_MKSTEMPS
388int mkstemps		__P((char *, int));
389#endif
390#ifndef HAVE_NANOSLEEP
391int nanosleep		__P((const struct timespec *, struct timespec *));
392#endif
393#ifndef HAVE_SETENV
394int setenv		__P((const char *, const char *, int));
395#endif
396#ifndef HAVE_UNSETENV
397int unsetenv		__P((const char *));
398#endif
399#ifndef HAVE_STRSIGNAL
400char *strsignal		__P((int));
401#endif
402#ifndef HAVE_SETSID
403pid_t setsid		__P((void));
404#endif
405
406#endif /* _SUDO_MISSING_H */
407