netscape-revival
nspr/src/md_SCO_SV.c
#include "prtypes.h"
#include "prosdep.h"
#include "prthread.h"
#include "prlog.h"
#include <sys/time.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/socket.h>
#include <signal.h>
#include <errno.h>
#include <ieeefp.h>
#include <sys/select.h>
/*
* Select doesn't work on NFS files.
*/
#define NFS_SELECT_BROKEN
#include "mdint.h"
void _MD_InitOS(int when)
{
_MD_InitUnixOS(when);
if (when == _MD_INIT_READY) {
fpsetmask( 0 );
}
}
prword_t *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
if (isCurrent) {
(void) sigsetjmp(CONTEXT(t),1);
}
*np = sizeof(CONTEXT(t)) / sizeof(prword_t);
return (prword_t*) CONTEXT(t);
}
/************************************************************************/
int _OS_OPEN(const char *path, int oflag, mode_t mode)
{
int rv = open(path, oflag, mode);
return (rv < 0 ? -errno : rv);
}
int _OS_CLOSE(int fd)
{
int rv = close(fd);
return (rv < 0 ? -errno : rv);
}
int _OS_READ(int fd, void *buf, unsigned nbyte)
{
int rv;
rv = read(fd, buf, nbyte);
return (rv < 0 ? -errno : rv);
}
int _OS_WRITE(int fd, void *buf, unsigned nbyte)
{
int rv;
rv = write(fd, buf, nbyte);
return (rv < 0 ? -errno : rv);
}
int _OS_SOCKET(int domain, int type, int flags)
{
int rv;
rv = socket(domain, type, flags);
return (rv < 0 ? -errno : rv);
}
int _OS_CONNECT(int fd, void *addr, int addrlen)
{
int rv;
rv = connect(fd, addr, addrlen);
return (rv < 0 ? -errno : rv);
}
int _OS_RECV(int s, char *buf, int len, int flags)
{
int rv;
rv = recv(s, buf, len, flags);
return (rv < 0 ? -errno : rv);
}
int _OS_SEND(int s, const char *msg, int len, int flags)
{
int rv;
rv = send(s, msg, len, flags);
return (rv < 0 ? -errno : rv);
}
int _OS_FCNTL(int filedes, int cmd, int arg)
{
int rv;
rv = fcntl(filedes, cmd, arg);
return (rv < 0 ? -errno : rv);
}
int _OS_IOCTL(int fd, int tag, int arg)
{
int rv;
rv = ioctl(fd, tag, arg);
if (rv < 0) {
return -errno;
}
return rv;
}
#ifndef NFS_SELECT_BROKEN
int _OS_SELECT(int fd, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
{
int rv;
rv = _R_OS_SELECT(fd, r, w, e, t);
if (rv < 0) {
return -errno;
}
return rv;
}
#else /* NFS_SELECT_BROKEN */
/*
* A select system call on an NFS file does NOT work! :-(
* This routine is a hack around that problem. If we get a
* failure based on invalid argument, we will look thru the
* lists of file descriptors, remove any NFS files and try
* the select again. If it succeeds we will add the NFS
* files to the list as ready to be serviced since they
* probably are. We will not support exceptional conditions
* on NFS files. There will not be any.
*
* Many thanks to donwo@sco.com for actually writting all this
* ugly code.
*/
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/fstyp.h>
static void RestoreNfsFds();
int
_OS_SELECT(int nfds, fd_set *ReadFds, fd_set *WriteFds, fd_set *ExceptFds,
struct timeval *TimeOut)
{
int ReadyFdCnt;
fd_set NfsReadFds;
fd_set NfsWriteFds;
fd_set NfsExceptFds;
struct timeval PollTimer;
int RwCnt;
int ExcptCnt;
ReadyFdCnt = _R_OS_SELECT(nfds, ReadFds, WriteFds, ExceptFds, TimeOut);
if ((ReadyFdCnt != -1) || (errno != EINVAL))
return(ReadyFdCnt);
RwCnt = DeleteNfsFds(nfds, ReadFds, &NfsReadFds) +
DeleteNfsFds(nfds, WriteFds, &NfsWriteFds);
ExcptCnt = DeleteNfsFds(nfds, ExceptFds, &NfsExceptFds);
if (!RwCnt && !ExcptCnt)
return(-1); /* Nothing NFS */
if (!RwCnt)
PollTimer = *TimeOut; /* The error was probably NFS exceptions */
else
{
PollTimer.tv_sec = 0;
PollTimer.tv_usec = 0;
}
ReadyFdCnt = _R_OS_SELECT(nfds, ReadFds, WriteFds, ExceptFds, &PollTimer);
if (ReadyFdCnt == -1)
return(ReadyFdCnt); /* Cannot fix this error */
RestoreNfsFds(nfds, ReadFds, &NfsReadFds);
RestoreNfsFds(nfds, WriteFds, &NfsWriteFds);
return(ReadyFdCnt + RwCnt);
}
static int
IsNfs(int Fd)
{
struct stat StatBuf;
struct statfs FsBuf;
static int NfsIndex = -1;
int fstatfs(int , struct statfs *, int , int);
int sysfs(int opcode, char *Name);
if (fstat(Fd, &StatBuf) ||
!S_ISREG(StatBuf.st_mode) ||
fstatfs(Fd, &FsBuf, sizeof(FsBuf), 0))
return(0); /* It is (probably) not an NFS file */
if ((NfsIndex < 0) &&
((NfsIndex = sysfs(GETFSIND, "NFS")) < 0))
return(0);
return((int)FsBuf.f_fstyp == NfsIndex);
}
static int
DeleteNfsFds(int nfds, fd_set *UsrSet, fd_set *NfsSet)
{
int NfsCnt = 0;
int Fd;
if (!UsrSet || !NfsSet)
return(NfsCnt);
FD_ZERO(NfsSet);
for (Fd = 0; Fd < nfds; ++Fd)
if (FD_ISSET(Fd, UsrSet) && IsNfs(Fd))
{
FD_SET(Fd, NfsSet);
FD_CLR(Fd, UsrSet);
++NfsCnt;
}
return(NfsCnt);
}
static void
RestoreNfsFds(int nfds, fd_set *UsrSet, fd_set *NfsSet)
{
int Fd;
if (!UsrSet || !NfsSet)
return;
for (Fd = 0; Fd < nfds; ++Fd)
if (FD_ISSET(Fd, NfsSet))
FD_SET(Fd, UsrSet);
}
#endif
#ifdef SCO_PM
#include <stdio.h>
#include <signal.h>
#include <syslog.h>
#include <locale.h>
#include <iforpmapi.h>
#include <licenseIDs.h>
/* #include "./lic_msg.h"*/
#ifndef _H_LIC_MSG
#define _H_LIC_MSG
#include <limits.h>
#include <nl_types.h>
#define MF_LIC "lic.cat@tcp"
#ifndef MC_FLAGS
#define MC_FLAGS NL_CAT_LOCALE
#endif
#ifndef MSGSTR
extern char *catgets_safe(nl_catd, int, int, char *);
#ifdef lint
#define MSGSTR(num,str) (str)
#define MSGSTR_SET(set,num,str) (str)
#else
#define MSGSTR(num,str) catgets_safe(catd, MS_LIC, (num), (str))
#define MSGSTR_SET(set,num,str) catgets_safe(catd, (set), (num), (str))
#endif
#endif
/* The following was generated from */
/* lic.gen */
#define MS_NET 1
#define NET_WRN 1
#define NET_PMD_FATAL_REQ 2
#define NET_PMD_ERR_REQ 3
#define NET_PMD_FATAL_INIT 4
#define NET_PMD_ERR_INIT 5
#define NET_PMD_SESS_TERM 6
#define NET_PMD_NO_LIC 7
#define NET_ALLOW_CONT 8
#endif /* _H_LIC_MSG */
#ifdef MCC_HTTPD
#include "base/ereport.h"
#endif
static nl_catd catd;
static sigset_t timer_set, oldset;
static int first_time = 1;
void PR_DisableClock()
{
if (first_time) {
sigemptyset(&timer_set);
sigaddset(&timer_set, SIGALRM);
first_time = 0;
}
sigprocmask(SIG_BLOCK, &timer_set, &oldset);
}
void PR_EnableClock()
{
sigprocmask(SIG_SETMASK, &oldset, 0);
}
/*
* sco_license_error
*/
void
sco_license_error(int level, char* fmt, char* msg)
{
#ifdef MCC_HTTPD
syslog(level, fmt, msg);
ereport(level, fmt, msg);
#else
syslog(level, fmt, msg);
fprintf(stderr, fmt, msg);
fprintf(stderr, "\n");
#endif
}
void
net_pm_signal_handler(
char *msg,
unsigned int flags,
ifor_pm_trns_hndl_t handle,
char *vmsg)
{
if (flags & IFOR_PM_VND_MSG) {
sco_license_error(LOG_INFO, "%s", vmsg);
}
if (flags & IFOR_PM_WARN) {
sco_license_error(LOG_WARNING, MSGSTR_SET(MS_NET, NET_WRN,
"Warning: %s"),msg);
}
if (flags & IFOR_PM_CONTINUE)
return;
if (flags & IFOR_PM_EXIT)
{
sco_license_error(LOG_ERR, MSGSTR_SET(MS_NET, NET_PMD_NO_LIC,
"Failed to obtain a license for this program."), NULL);
exit(1);
}
if (flags & IFOR_PM_EXIT)
{
sco_license_error(LOG_ERR, MSGSTR_SET(MS_NET, NET_PMD_SESS_TERM,
"Program terminated by policy manager."), NULL);
exit(2);
}
return;
}
/*
* request_license
* version is set to "everest" as per Sco's instructions.
* It's some sort of work-around for their license manager.
*/
void request_license(int p_id, char *progname)
{
int status, n;
unsigned long prod_id;
char *version = "everest";
ifor_pm_trns_hndl_t handle;
int res;
PR_DisableClock();
#ifdef INTL
setlocale(LC_ALL, "");
catd = catopen (MF_LIC,MC_FLAGS);
openlog(progname, LOG_PID, LOG_DAEMON);
#endif
/* Contact the license server.
* We set up a handler, and perhaps a signal, that the license
* server can use to contact us.
*/
res = ifor_pm_init_sco(net_pm_signal_handler,IFOR_PM_NO_SIGNAL);
switch (res)
{
case IFOR_PM_OK :
case IFOR_PM_REINIT :
break;
case IFOR_PM_BAD_PARAM :
sco_license_error(LOG_WARNING, MSGSTR_SET(MS_NET, NET_PMD_ERR_INIT,
"An error has occurred during a call to initialize the license server."), NULL);
break;
case IFOR_PM_FATAL :
sco_license_error(LOG_ERR, MSGSTR_SET(MS_NET, NET_PMD_FATAL_INIT,
"fatal error while trying to initialize license server."), NULL);
exit(3);
default :
break;
}
/* Try to grab a license */
res = ifor_pm_request_sco(p_id,version,IFOR_PM_SYNC,&handle);
switch(res)
{
case IFOR_PM_OK :
break;
case IFOR_PM_BAD_PARAM :
sco_license_error(LOG_WARNING, MSGSTR_SET(MS_NET, NET_PMD_ERR_REQ,
"An error has occurred during a call to request a license."), NULL);
sco_license_error(LOG_WARNING, MSGSTR_SET(MS_NET, NET_ALLOW_CONT,
"Allowing session to continue."), NULL);
break;
case IFOR_PM_FATAL :
sco_license_error(LOG_ERR, MSGSTR_SET(MS_NET, NET_PMD_FATAL_REQ,
"fatal error while trying to request license."), NULL);
exit(4);
default :
break;
}
PR_EnableClock();
}
#endif