12311Sjkh/* Copyright 1988,1990,1993,1994 by Paul Vixie
22311Sjkh * All rights reserved
32311Sjkh *
42311Sjkh * Distribute freely, except: don't remove my name from the source or
52311Sjkh * documentation (don't take credit for my work), mark your changes (don't
62311Sjkh * get me blamed for your possible bugs), don't alter or remove this
72311Sjkh * notice.  May be sold if buildable source is provided to buyer.  No
82311Sjkh * warrantee of any kind, express or implied, is included with this
92311Sjkh * software; use at your own risk, responsibility for damages (if any) to
102311Sjkh * anyone resulting from the use of this software rests entirely with the
112311Sjkh * user.
122311Sjkh *
132311Sjkh * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
142311Sjkh * I'll try to keep a version up to date.  I can be reached as follows:
152311Sjkh * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
162311Sjkh */
172311Sjkh
182311Sjkh#if !defined(lint) && !defined(LINT)
1950479Speterstatic char rcsid[] = "$FreeBSD: releng/10.3/usr.sbin/cron/lib/compat.c 69793 2000-12-09 09:35:55Z obrien $";
202311Sjkh#endif
212311Sjkh
222311Sjkh/* vix 30dec93 [broke this out of misc.c - see RCS log for history]
232311Sjkh * vix 15jan87 [added TIOCNOTTY, thanks csg@pyramid]
242311Sjkh */
252311Sjkh
262311Sjkh
272311Sjkh#include "cron.h"
282311Sjkh#ifdef NEED_GETDTABLESIZE
292311Sjkh# include <limits.h>
302311Sjkh#endif
312311Sjkh#if defined(NEED_SETSID) && defined(BSD)
322311Sjkh# include <sys/ioctl.h>
332311Sjkh#endif
342311Sjkh#include <errno.h>
3569793Sobrien#include <paths.h>
362311Sjkh
372311Sjkh
382311Sjkh/* the code does not depend on any of vfork's
392311Sjkh * side-effects; it just uses it as a quick
402311Sjkh * fork-and-exec.
412311Sjkh */
422311Sjkh#ifdef NEED_VFORK
432311SjkhPID_T
442311Sjkhvfork() {
452311Sjkh	return (fork());
462311Sjkh}
472311Sjkh#endif
482311Sjkh
492311Sjkh
502311Sjkh#ifdef NEED_STRDUP
512311Sjkhchar *
522311Sjkhstrdup(str)
532311Sjkh	char	*str;
542311Sjkh{
552311Sjkh	char	*temp;
562311Sjkh
5720573Spst	if ((temp = malloc(strlen(str) + 1)) == NULL) {
5820573Spst		errno = ENOMEM;
5920573Spst		return NULL;
6020573Spst	}
612311Sjkh	(void) strcpy(temp, str);
622311Sjkh	return temp;
632311Sjkh}
642311Sjkh#endif
652311Sjkh
662311Sjkh
672311Sjkh#ifdef NEED_STRERROR
682311Sjkhchar *
692311Sjkhstrerror(error)
702311Sjkh	int error;
712311Sjkh{
722311Sjkh	extern char *sys_errlist[];
732311Sjkh	extern int sys_nerr;
742311Sjkh	static char buf[32];
752311Sjkh
762311Sjkh	if ((error <= sys_nerr) && (error > 0)) {
772311Sjkh		return sys_errlist[error];
782311Sjkh	}
792311Sjkh
802311Sjkh	sprintf(buf, "Unknown error: %d", error);
812311Sjkh	return buf;
822311Sjkh}
832311Sjkh#endif
842311Sjkh
852311Sjkh
862311Sjkh#ifdef NEED_STRCASECMP
872311Sjkhint
882311Sjkhstrcasecmp(left, right)
892311Sjkh	char	*left;
902311Sjkh	char	*right;
912311Sjkh{
922311Sjkh	while (*left && (MkLower(*left) == MkLower(*right))) {
932311Sjkh		left++;
942311Sjkh		right++;
952311Sjkh	}
962311Sjkh	return MkLower(*left) - MkLower(*right);
972311Sjkh}
982311Sjkh#endif
992311Sjkh
1002311Sjkh
1012311Sjkh#ifdef NEED_SETSID
1022311Sjkhint
1032311Sjkhsetsid()
1042311Sjkh{
1052311Sjkh	int	newpgrp;
1062311Sjkh# if defined(BSD)
1072311Sjkh	int	fd;
1082311Sjkh#  if defined(POSIX)
1092311Sjkh	newpgrp = setpgid((pid_t)0, getpid());
1102311Sjkh#  else
1112311Sjkh	newpgrp = setpgrp(0, getpid());
1122311Sjkh#  endif
11369793Sobrien	if ((fd = open(_PATH_TTY, 2)) >= 0)
1142311Sjkh	{
1152311Sjkh		(void) ioctl(fd, TIOCNOTTY, (char*)0);
1162311Sjkh		(void) close(fd);
1172311Sjkh	}
1182311Sjkh# else /*BSD*/
1192311Sjkh	newpgrp = setpgrp();
1202311Sjkh
12169793Sobrien	(void) close(STDIN);	(void) open(_PATH_DEVNULL, 0);
12269793Sobrien	(void) close(STDOUT);	(void) open(_PATH_DEVNULL, 1);
12369793Sobrien	(void) close(STDERR);	(void) open(_PATH_DEVNULL, 2);
1242311Sjkh# endif /*BSD*/
1252311Sjkh	return newpgrp;
1262311Sjkh}
1272311Sjkh#endif /*NEED_SETSID*/
1282311Sjkh
1292311Sjkh
1302311Sjkh#ifdef NEED_GETDTABLESIZE
1312311Sjkhint
1322311Sjkhgetdtablesize() {
1332311Sjkh#ifdef _SC_OPEN_MAX
1342311Sjkh	return sysconf(_SC_OPEN_MAX);
1352311Sjkh#else
1362311Sjkh	return _POSIX_OPEN_MAX;
1372311Sjkh#endif
1382311Sjkh}
1392311Sjkh#endif
1402311Sjkh
1412311Sjkh
1422311Sjkh#ifdef NEED_FLOCK
1432311Sjkh/* The following flock() emulation snarfed intact *) from the HP-UX
1442311Sjkh * "BSD to HP-UX porting tricks" maintained by
1452311Sjkh * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
1462311Sjkh * from the version "last updated: 11-Jan-1993"
1472311Sjkh * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
1482311Sjkh * *) well, almost, had to K&R the function entry, HPUX "cc"
1492311Sjkh * does not grok ANSI function prototypes */
15020573Spst
1512311Sjkh/*
1522311Sjkh * flock (fd, operation)
1532311Sjkh *
1542311Sjkh * This routine performs some file locking like the BSD 'flock'
1552311Sjkh * on the object described by the int file descriptor 'fd',
1562311Sjkh * which must already be open.
1572311Sjkh *
1582311Sjkh * The operations that are available are:
1592311Sjkh *
1602311Sjkh * LOCK_SH  -  get a shared lock.
1612311Sjkh * LOCK_EX  -  get an exclusive lock.
1622311Sjkh * LOCK_NB  -  don't block (must be ORed with LOCK_SH or LOCK_EX).
1632311Sjkh * LOCK_UN  -  release a lock.
1642311Sjkh *
1652311Sjkh * Return value: 0 if lock successful, -1 if failed.
1662311Sjkh *
1672311Sjkh * Note that whether the locks are enforced or advisory is
1682311Sjkh * controlled by the presence or absence of the SETGID bit on
1692311Sjkh * the executable.
1702311Sjkh *
1712311Sjkh * Note that there is no difference between shared and exclusive
1722311Sjkh * locks, since the 'lockf' system call in SYSV doesn't make any
1732311Sjkh * distinction.
1742311Sjkh *
1752311Sjkh * The file "<sys/file.h>" should be modified to contain the definitions
1762311Sjkh * of the available operations, which must be added manually (see below
1772311Sjkh * for the values).
1782311Sjkh */
1792311Sjkh
1802311Sjkh/* this code has been reformatted by vixie */
1812311Sjkh
1822311Sjkhint
1832311Sjkhflock(fd, operation)
1842311Sjkh	int fd;
1852311Sjkh	int operation;
1862311Sjkh{
1872311Sjkh	int i;
1882311Sjkh
1892311Sjkh	switch (operation) {
1902311Sjkh	case LOCK_SH:		/* get a shared lock */
1912311Sjkh	case LOCK_EX:		/* get an exclusive lock */
1922311Sjkh		i = lockf (fd, F_LOCK, 0);
1932311Sjkh		break;
1942311Sjkh
1952311Sjkh	case LOCK_SH|LOCK_NB:	/* get a non-blocking shared lock */
1962311Sjkh	case LOCK_EX|LOCK_NB:	/* get a non-blocking exclusive lock */
1972311Sjkh		i = lockf (fd, F_TLOCK, 0);
1982311Sjkh		if (i == -1)
1992311Sjkh			if ((errno == EAGAIN) || (errno == EACCES))
2002311Sjkh				errno = EWOULDBLOCK;
2012311Sjkh		break;
2022311Sjkh
2032311Sjkh	case LOCK_UN:		/* unlock */
2042311Sjkh		i = lockf (fd, F_ULOCK, 0);
2052311Sjkh		break;
20620573Spst
2072311Sjkh	default:		/* can't decipher operation */
2082311Sjkh		i = -1;
2092311Sjkh		errno = EINVAL;
2102311Sjkh		break;
2112311Sjkh	}
21220573Spst
2132311Sjkh	return (i);
2142311Sjkh}
2152311Sjkh#endif /*NEED_FLOCK*/
2162311Sjkh
2172311Sjkh
2182311Sjkh#ifdef NEED_SETENV
2192311Sjkhint
2202311Sjkhsetenv(name, value, overwrite)
2212311Sjkh	char *name, *value;
2222311Sjkh	int overwrite;
2232311Sjkh{
2242311Sjkh	char *tmp;
2252311Sjkh
2262311Sjkh	if (overwrite && getenv(name))
2272311Sjkh		return -1;
2282311Sjkh
2292311Sjkh	if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) {
2302311Sjkh		errno = ENOMEM;
2312311Sjkh		return -1;
2322311Sjkh	}
2332311Sjkh
23420573Spst	sprintf(tmp, "%s=%s", name, value);
2352311Sjkh	return putenv(tmp);	/* intentionally orphan 'tmp' storage */
2362311Sjkh}
2372311Sjkh#endif
238