1/* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice.  May be sold if buildable source is provided to buyer.  No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date.  I can be reached as follows:
15 * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
16 */
17
18#if !defined(lint) && !defined(LINT)
19static char rcsid[] = "$FreeBSD: src/usr.sbin/cron/lib/compat.c,v 1.7 2000/12/09 09:35:44 obrien Exp $";
20#endif
21
22/* vix 30dec93 [broke this out of misc.c - see RCS log for history]
23 * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid]
24 */
25
26
27#include "cron.h"
28#ifdef NEED_GETDTABLESIZE
29# include <limits.h>
30#endif
31#if defined(NEED_SETSID) && defined(BSD)
32# include <sys/ioctl.h>
33#endif
34#include <errno.h>
35#include <paths.h>
36
37
38/* the code does not depend on any of vfork's
39 * side-effects; it just uses it as a quick
40 * fork-and-exec.
41 */
42#ifdef NEED_VFORK
43PID_T
44vfork() {
45	return (fork());
46}
47#endif
48
49
50#ifdef NEED_STRDUP
51char *
52strdup(str)
53	char	*str;
54{
55	char	*temp;
56
57	if ((temp = malloc(strlen(str) + 1)) == NULL) {
58		errno = ENOMEM;
59		return NULL;
60	}
61	(void) strcpy(temp, str);
62	return temp;
63}
64#endif
65
66
67#ifdef NEED_STRERROR
68char *
69strerror(error)
70	int error;
71{
72	extern char *sys_errlist[];
73	extern int sys_nerr;
74	static char buf[32];
75
76	if ((error <= sys_nerr) && (error > 0)) {
77		return sys_errlist[error];
78	}
79
80	sprintf(buf, "Unknown error: %d", error);
81	return buf;
82}
83#endif
84
85
86#ifdef NEED_STRCASECMP
87int
88strcasecmp(left, right)
89	char	*left;
90	char	*right;
91{
92	while (*left && (MkLower(*left) == MkLower(*right))) {
93		left++;
94		right++;
95	}
96	return MkLower(*left) - MkLower(*right);
97}
98#endif
99
100
101#ifdef NEED_SETSID
102int
103setsid()
104{
105	int	newpgrp;
106# if defined(BSD)
107	int	fd;
108#  if defined(POSIX)
109	newpgrp = setpgid((pid_t)0, getpid());
110#  else
111	newpgrp = setpgrp(0, getpid());
112#  endif
113	if ((fd = open(_PATH_TTY, 2)) >= 0)
114	{
115		(void) ioctl(fd, TIOCNOTTY, (char*)0);
116		(void) close(fd);
117	}
118# else /*BSD*/
119	newpgrp = setpgrp();
120
121	(void) close(STDIN);	(void) open(_PATH_DEVNULL, 0);
122	(void) close(STDOUT);	(void) open(_PATH_DEVNULL, 1);
123	(void) close(STDERR);	(void) open(_PATH_DEVNULL, 2);
124# endif /*BSD*/
125	return newpgrp;
126}
127#endif /*NEED_SETSID*/
128
129
130#ifdef NEED_GETDTABLESIZE
131int
132getdtablesize() {
133#ifdef _SC_OPEN_MAX
134	return sysconf(_SC_OPEN_MAX);
135#else
136	return _POSIX_OPEN_MAX;
137#endif
138}
139#endif
140
141
142#ifdef NEED_FLOCK
143/* The following flock() emulation snarfed intact *) from the HP-UX
144 * "BSD to HP-UX porting tricks" maintained by
145 * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
146 * from the version "last updated: 11-Jan-1993"
147 * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
148 * *) well, almost, had to K&R the function entry, HPUX "cc"
149 * does not grok ANSI function prototypes */
150
151/*
152 * flock (fd, operation)
153 *
154 * This routine performs some file locking like the BSD 'flock'
155 * on the object described by the int file descriptor 'fd',
156 * which must already be open.
157 *
158 * The operations that are available are:
159 *
160 * LOCK_SH  -  get a shared lock.
161 * LOCK_EX  -  get an exclusive lock.
162 * LOCK_NB  -  don't block (must be ORed with LOCK_SH or LOCK_EX).
163 * LOCK_UN  -  release a lock.
164 *
165 * Return value: 0 if lock successful, -1 if failed.
166 *
167 * Note that whether the locks are enforced or advisory is
168 * controlled by the presence or absence of the SETGID bit on
169 * the executable.
170 *
171 * Note that there is no difference between shared and exclusive
172 * locks, since the 'lockf' system call in SYSV doesn't make any
173 * distinction.
174 *
175 * The file "<sys/file.h>" should be modified to contain the definitions
176 * of the available operations, which must be added manually (see below
177 * for the values).
178 */
179
180/* this code has been reformatted by vixie */
181
182int
183flock(fd, operation)
184	int fd;
185	int operation;
186{
187	int i;
188
189	switch (operation) {
190	case LOCK_SH:		/* get a shared lock */
191	case LOCK_EX:		/* get an exclusive lock */
192		i = lockf (fd, F_LOCK, 0);
193		break;
194
195	case LOCK_SH|LOCK_NB:	/* get a non-blocking shared lock */
196	case LOCK_EX|LOCK_NB:	/* get a non-blocking exclusive lock */
197		i = lockf (fd, F_TLOCK, 0);
198		if (i == -1)
199			if ((errno == EAGAIN) || (errno == EACCES))
200				errno = EWOULDBLOCK;
201		break;
202
203	case LOCK_UN:		/* unlock */
204		i = lockf (fd, F_ULOCK, 0);
205		break;
206
207	default:		/* can't decipher operation */
208		i = -1;
209		errno = EINVAL;
210		break;
211	}
212
213	return (i);
214}
215#endif /*NEED_FLOCK*/
216
217
218#ifdef NEED_SETENV
219int
220setenv(name, value, overwrite)
221	char *name, *value;
222	int overwrite;
223{
224	char *tmp;
225
226	if (overwrite && getenv(name))
227		return -1;
228
229	if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) {
230		errno = ENOMEM;
231		return -1;
232	}
233
234	sprintf(tmp, "%s=%s", name, value);
235	return putenv(tmp);	/* intentionally orphan 'tmp' storage */
236}
237#endif
238