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