compat.c revision 2311
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)
192311Sjkhstatic char rcsid[] = "$Id: compat.c,v 1.6 1994/01/15 20:43:43 vixie Exp $";
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>
352311Sjkh
362311Sjkh
372311Sjkh/* the code does not depend on any of vfork's
382311Sjkh * side-effects; it just uses it as a quick
392311Sjkh * fork-and-exec.
402311Sjkh */
412311Sjkh#ifdef NEED_VFORK
422311SjkhPID_T
432311Sjkhvfork() {
442311Sjkh	return (fork());
452311Sjkh}
462311Sjkh#endif
472311Sjkh
482311Sjkh
492311Sjkh#ifdef NEED_STRDUP
502311Sjkhchar *
512311Sjkhstrdup(str)
522311Sjkh	char	*str;
532311Sjkh{
542311Sjkh	char	*temp;
552311Sjkh
562311Sjkh	temp = malloc(strlen(str) + 1);
572311Sjkh	(void) strcpy(temp, str);
582311Sjkh	return temp;
592311Sjkh}
602311Sjkh#endif
612311Sjkh
622311Sjkh
632311Sjkh#ifdef NEED_STRERROR
642311Sjkhchar *
652311Sjkhstrerror(error)
662311Sjkh	int error;
672311Sjkh{
682311Sjkh	extern char *sys_errlist[];
692311Sjkh	extern int sys_nerr;
702311Sjkh	static char buf[32];
712311Sjkh
722311Sjkh	if ((error <= sys_nerr) && (error > 0)) {
732311Sjkh		return sys_errlist[error];
742311Sjkh	}
752311Sjkh
762311Sjkh	sprintf(buf, "Unknown error: %d", error);
772311Sjkh	return buf;
782311Sjkh}
792311Sjkh#endif
802311Sjkh
812311Sjkh
822311Sjkh#ifdef NEED_STRCASECMP
832311Sjkhint
842311Sjkhstrcasecmp(left, right)
852311Sjkh	char	*left;
862311Sjkh	char	*right;
872311Sjkh{
882311Sjkh	while (*left && (MkLower(*left) == MkLower(*right))) {
892311Sjkh		left++;
902311Sjkh		right++;
912311Sjkh	}
922311Sjkh	return MkLower(*left) - MkLower(*right);
932311Sjkh}
942311Sjkh#endif
952311Sjkh
962311Sjkh
972311Sjkh#ifdef NEED_SETSID
982311Sjkhint
992311Sjkhsetsid()
1002311Sjkh{
1012311Sjkh	int	newpgrp;
1022311Sjkh# if defined(BSD)
1032311Sjkh	int	fd;
1042311Sjkh#  if defined(POSIX)
1052311Sjkh	newpgrp = setpgid((pid_t)0, getpid());
1062311Sjkh#  else
1072311Sjkh	newpgrp = setpgrp(0, getpid());
1082311Sjkh#  endif
1092311Sjkh	if ((fd = open("/dev/tty", 2)) >= 0)
1102311Sjkh	{
1112311Sjkh		(void) ioctl(fd, TIOCNOTTY, (char*)0);
1122311Sjkh		(void) close(fd);
1132311Sjkh	}
1142311Sjkh# else /*BSD*/
1152311Sjkh	newpgrp = setpgrp();
1162311Sjkh
1172311Sjkh	(void) close(STDIN);	(void) open("/dev/null", 0);
1182311Sjkh	(void) close(STDOUT);	(void) open("/dev/null", 1);
1192311Sjkh	(void) close(STDERR);	(void) open("/dev/null", 2);
1202311Sjkh# endif /*BSD*/
1212311Sjkh	return newpgrp;
1222311Sjkh}
1232311Sjkh#endif /*NEED_SETSID*/
1242311Sjkh
1252311Sjkh
1262311Sjkh#ifdef NEED_GETDTABLESIZE
1272311Sjkhint
1282311Sjkhgetdtablesize() {
1292311Sjkh#ifdef _SC_OPEN_MAX
1302311Sjkh	return sysconf(_SC_OPEN_MAX);
1312311Sjkh#else
1322311Sjkh	return _POSIX_OPEN_MAX;
1332311Sjkh#endif
1342311Sjkh}
1352311Sjkh#endif
1362311Sjkh
1372311Sjkh
1382311Sjkh#ifdef NEED_FLOCK
1392311Sjkh/* The following flock() emulation snarfed intact *) from the HP-UX
1402311Sjkh * "BSD to HP-UX porting tricks" maintained by
1412311Sjkh * system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
1422311Sjkh * from the version "last updated: 11-Jan-1993"
1432311Sjkh * Snarfage done by Jarkko Hietaniemi <Jarkko.Hietaniemi@hut.fi>
1442311Sjkh * *) well, almost, had to K&R the function entry, HPUX "cc"
1452311Sjkh * does not grok ANSI function prototypes */
1462311Sjkh
1472311Sjkh/*
1482311Sjkh * flock (fd, operation)
1492311Sjkh *
1502311Sjkh * This routine performs some file locking like the BSD 'flock'
1512311Sjkh * on the object described by the int file descriptor 'fd',
1522311Sjkh * which must already be open.
1532311Sjkh *
1542311Sjkh * The operations that are available are:
1552311Sjkh *
1562311Sjkh * LOCK_SH  -  get a shared lock.
1572311Sjkh * LOCK_EX  -  get an exclusive lock.
1582311Sjkh * LOCK_NB  -  don't block (must be ORed with LOCK_SH or LOCK_EX).
1592311Sjkh * LOCK_UN  -  release a lock.
1602311Sjkh *
1612311Sjkh * Return value: 0 if lock successful, -1 if failed.
1622311Sjkh *
1632311Sjkh * Note that whether the locks are enforced or advisory is
1642311Sjkh * controlled by the presence or absence of the SETGID bit on
1652311Sjkh * the executable.
1662311Sjkh *
1672311Sjkh * Note that there is no difference between shared and exclusive
1682311Sjkh * locks, since the 'lockf' system call in SYSV doesn't make any
1692311Sjkh * distinction.
1702311Sjkh *
1712311Sjkh * The file "<sys/file.h>" should be modified to contain the definitions
1722311Sjkh * of the available operations, which must be added manually (see below
1732311Sjkh * for the values).
1742311Sjkh */
1752311Sjkh
1762311Sjkh/* this code has been reformatted by vixie */
1772311Sjkh
1782311Sjkhint
1792311Sjkhflock(fd, operation)
1802311Sjkh	int fd;
1812311Sjkh	int operation;
1822311Sjkh{
1832311Sjkh	int i;
1842311Sjkh
1852311Sjkh	switch (operation) {
1862311Sjkh	case LOCK_SH:		/* get a shared lock */
1872311Sjkh	case LOCK_EX:		/* get an exclusive lock */
1882311Sjkh		i = lockf (fd, F_LOCK, 0);
1892311Sjkh		break;
1902311Sjkh
1912311Sjkh	case LOCK_SH|LOCK_NB:	/* get a non-blocking shared lock */
1922311Sjkh	case LOCK_EX|LOCK_NB:	/* get a non-blocking exclusive lock */
1932311Sjkh		i = lockf (fd, F_TLOCK, 0);
1942311Sjkh		if (i == -1)
1952311Sjkh			if ((errno == EAGAIN) || (errno == EACCES))
1962311Sjkh				errno = EWOULDBLOCK;
1972311Sjkh		break;
1982311Sjkh
1992311Sjkh	case LOCK_UN:		/* unlock */
2002311Sjkh		i = lockf (fd, F_ULOCK, 0);
2012311Sjkh		break;
2022311Sjkh
2032311Sjkh	default:		/* can't decipher operation */
2042311Sjkh		i = -1;
2052311Sjkh		errno = EINVAL;
2062311Sjkh		break;
2072311Sjkh	}
2082311Sjkh
2092311Sjkh	return (i);
2102311Sjkh}
2112311Sjkh#endif /*NEED_FLOCK*/
2122311Sjkh
2132311Sjkh
2142311Sjkh#ifdef NEED_SETENV
2152311Sjkhint
2162311Sjkhsetenv(name, value, overwrite)
2172311Sjkh	char *name, *value;
2182311Sjkh	int overwrite;
2192311Sjkh{
2202311Sjkh	char *tmp;
2212311Sjkh
2222311Sjkh	if (overwrite && getenv(name))
2232311Sjkh		return -1;
2242311Sjkh
2252311Sjkh	if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) {
2262311Sjkh		errno = ENOMEM;
2272311Sjkh		return -1;
2282311Sjkh	}
2292311Sjkh
2302311Sjkh	sprintf("%s=%s", name, value);
2312311Sjkh	return putenv(tmp);	/* intentionally orphan 'tmp' storage */
2322311Sjkh}
2332311Sjkh#endif
234