/********************************************************************
* wilkinson
* 3.16VMS
* 1995/09/25 11:11
* gopher_root1:[gopher.g2.vms2_13.object]compatible.c,v
* Exp
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: compatible.c
* Compatibility routines
*********************************************************************
* Revision History:
* compatible.c,v
* Revision 3.16VMS 1995/09/25 11:11 wilkinson
* Consolodate VMS/Unix source code for server as well as client
* - move syslog() routines here so available to both server and client
* - use __VMS instead of VMS as trigger for VMS items
*
* Revision 3.16 1995/02/06 22:14:22 lindner
* Remove const
*
* Revision 3.15 1994/12/15 17:30:16 lindner
* A replacement fgetpwent
*
* Revision 3.14 1994/07/21 22:18:45 lindner
* Add putenv() compat code
*
* Revision 3.13 1994/04/25 03:34:34 lindner
* Put back alpha patch (Fote)
*
* Revision 3.12 1994/04/08 20:05:55 lindner
* gcc -Wall fixes
*
* Revision 3.11 1994/04/01 04:44:28 lindner
* Fix for alpha VMS
*
* Revision 3.10 1994/03/30 21:38:39 lindner
* Remove some VMS code
*
* Revision 3.9 1994/03/17 04:38:45 lindner
* VMS weird directory routines
*
* Revision 3.8 1994/03/08 03:24:09 lindner
* Waitpid for vms
*
* Revision 3.7 1993/10/27 18:51:10 lindner
* Updates for VMS files/records
*
* Revision 3.6 1993/09/03 03:26:39 lindner
* Better VMS tempnam() implementation
*
* Revision 3.5 1993/06/22 05:53:17 lindner
* Added getdtablesize() option
*
* Revision 3.4 1993/04/15 21:36:30 lindner
* Emulation of geteuid calls for HPs
*
* Revision 3.3 1993/03/18 22:27:46 lindner
* better portable tempnam()
*
* Revision 3.2 1993/02/19 21:33:27 lindner
* Gopher1.2b2 release
*
* Revision 3.1.1.1 1993/02/11 18:03:05 lindner
* Gopher+1.2beta release
*
* Revision 1.4 1993/01/17 03:46:12 lindner
* Fixed tempnam for VMS
*
* Revision 1.3 1993/01/08 23:13:55 lindner
* Added more VMS mods from jqj
*
*
*********************************************************************/
/*
* Some functions that aren't implemented on every machine on the net
*
* definitions should be in the form "NO_FNNAME"
* compatible.h looks at preprocessor symbols and automatically defines
* many of the NO_FNNAME options
*
*/
#include <string.h>
#include <stdio.h>
#include "Malloc.h" /*** For NULL ***/
#include "compatible.h"
/*** For machines that don't have strstr ***/
#if defined(NOSTRSTR)
char *
strstr(host_name, cp)
char *host_name;
char *cp;
{
int i, j;
for (i = 0; i < strlen(host_name); i++) {
j = strncmp(host_name+i, cp, strlen(cp));
if (j == 0)
return(host_name+i);
}
return(NULL);
}
#endif
#if defined(sequent)
#include <varargs.h>
vsprintf(va_alist)
va_dcl
{
;
}
vfprintf(va_alist)
va_dcl
{
;
}
#endif
#if defined(NO_TEMPNAM)
/* A tip of the hat to the developers of elm 2.4pl17, from whence
the non-VMS portion of this routine comes.
*/
/* and a tempnam for temporary files */
static int cnt = 0;
char *tempnam(dir, pfx)
char *dir;
char *pfx;
{
char space[512];
char *newspace;
#ifdef __VMS
if (dir == NULL) {
dir = "sys$scratch:";
} else if (*dir == '\0') {
dir = "sys$scratch:";
}
if (pfx == NULL) {
pfx = "gopher.$";
} else if (*pfx == '\0') {
pfx = "gopher.$";
}
sprintf(space, "%s%s%d%d", dir, pfx, getpid(), cnt);
#else
if (dir == NULL) {
dir = "/usr/tmp";
} else if (*dir == '\0') {
dir = "/usr/tmp";
}
if (pfx == NULL) {
pfx = "";
}
sprintf(space, "%s/%s%d.%d", dir, pfx, getpid(), cnt);
#endif
cnt++;
newspace = (char *)malloc(strlen(space) + 1);
if (newspace != NULL) {
strcpy(newspace, space);
}
return newspace;
}
#endif
#if defined(NO_STRDUP)
char *strdup(str)
char *str;
{
int len;
char *temp;
if (str == NULL) return(NULL);
len = strlen(str);
temp = (char *) malloc(sizeof(char) * len + 1);
strcpy(temp, str);
return(temp);
}
#endif
#if defined(NO_TZSET)
void
tzset()
{
;
}
#endif
#if defined(NO_STRCASECMP)
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Modified for use on VMS by Earl Fogel, University of Saskatchewan
* Computing Services, January 1992
*/
typedef unsigned char U_char;
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
static U_char charmap[] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
};
int
strcasecmp(s1, s2)
const char *s1, *s2;
{
register const U_char *cm = charmap,
*us1 = (const U_char *)s1,
*us2 = (const U_char *)s2;
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
return (0);
return (cm[*us1] - cm[*--us2]);
}
int
strncasecmp(s1, s2, n)
const char *s1, *s2;
register size_t n;
{
if (n != 0) {
register const U_char *cm = charmap,
*us1 = (const U_char *)s1,
*us2 = (const U_char *)s2;
do {
if (cm[*us1] != cm[*us2++])
return (cm[*us1] - cm[*--us2]);
if (*us1++ == '\0')
break;
} while (--n != 0);
}
return (0);
}
#endif
#if defined(NO_GETDTABLESIZE)
int getdtablesize()
{
struct rlimit rlp;
rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY;
if (getrlimit( RLIMIT_NOFILE, &rlp ) )
return(-1);
fds = rlp.rlim_cur;
}
#endif
#if defined(__VMS)
/* In all versions of VMS, fopen() and open() are needlessly inefficient.
* Define jacket routines to do file opens with more sensible parameters
* than the VAXCRTL default.
* [Should we really be doing this for EVERY fopen() and open()?]
*/
#ifdef fopen
#undef fopen
#endif
#ifdef open
#undef open
#endif
FILE *fopen_VAR ( name, mode )
char *name, *mode;
{
return fopen ( name, mode, "rfm=var","rat=cr","mbc=32" );
}
FILE *fopen_FIX ( name, mode )
char *name, *mode;
{
return fopen ( name, mode, "rfm=fix","mrs=512","mbc=32" );
}
#ifdef VMS_SERVER
int vaxc$errno_stv;
#include <rms.h>
#include <errno.h>
FILE *fopen_VMSopt ( name, mode , alq, deq)
char *name, *mode, *alq, *deq;
{
struct FAB fab;
int status;
FILE *opened;
errno = vaxc$errno = vaxc$errno_stv = 0;
if (strcmp(mode,"a")==0)
opened = fopen (name, mode, "mbc=32", alq, deq);
else
opened = fopen ( name, mode, "mbc=32" );
if (opened==NULL) {
fab = cc$rms_fab;
fab.fab$l_fna = name;
fab.fab$b_fns = strlen(fab.fab$l_fna);
if (((status = SYS$OPEN(&fab, 0, 0)) &1) != 1) {
vaxc$errno = fab.fab$l_sts;
vaxc$errno_stv = fab.fab$l_stv;
}
else SYS$CLOSE(&fab,0,0);
}
return opened;
}
#else
FILE *fopen_VMSopt ( name, mode )
char *name, *mode;
{
return fopen ( name, mode, "mbc=32" );
}
#endif
int open_VMSopt ( name, flags, mode )
char *name;
int flags;
unsigned int mode;
{
return open ( name, flags, mode, "mbc=32");
}
#endif
#if defined(VMS_SERVER) && !defined(MULTINET)
/* Multinet defines a handy vms_errno_string() that essentially packages
* strerror with no parameters. (This insulates other platforms from
* VMS' oddball two-argument strerror.) We need to supply it here for
* other IP packages under VMS.
*/
char *vms_errno_string (void) { return(strerror(errno, vaxc$errno)); }
#endif
#if defined(__VMS) || defined(NO_WAITPID_WAIT3)
# include "Wait.h"
pid_t waitpid(pid, status, options)
pid_t pid;
int *status;
int options;
{
int zepid;
while ((zepid = wait(status)) != pid && pid != -1)
/** Should check and make sure process exited... **/
;
return(zepid);
}
#endif
/*
* This is an ugly hack for now, since we only use strftime in one
* place..... so far..
*/
#if defined(NO_STRFTIME)
# include <time.h>
int strftime(buf, bufsize, fmt, tm)
char *buf;
int bufsize;
char *fmt;
struct tm *tm;
{
sprintf(buf, "%4d%02d%02d%02d%02d%02d\n",
tm->tm_year, tm->tm_mon+1,tm->tm_mday,
tm->tm_hour, tm->tm_mon, tm->tm_sec);
}
#endif
/*
* This code was stolen from cnews. Modified to make "newenv" static so
* that realloc() can be used on subsequent calls to avoid memory leaks.
*
* We only need this if Configure said there isn't a putenv() in libc.
*/
#ifndef __VMS
#ifdef NO_PUTENV /*{*/
/* peculiar return values */
#define WORKED 0
#define FAILED 1
int
putenv(var) /* put var in the environment */
char *var;
{
register char **envp;
register int oldenvcnt;
extern char **environ;
static char **newenv = NULL;
/* count variables, look for var */
for (envp = environ; *envp != 0; envp++) {
register char *varp = var, *ep = *envp;
register int namesame;
namesame = 0;
for (; *varp == *ep && *varp != '\0'; ++ep, ++varp)
if (*varp == '=')
namesame = 1;
if (*varp == *ep && *ep == '\0')
return WORKED; /* old & new var's are the same */
if (namesame) {
*envp = var; /* replace var with new value */
return WORKED;
}
}
oldenvcnt = envp - environ;
/* allocate new environment with room for one more variable */
if (newenv == NULL)
newenv = (char **)malloc((unsigned)((oldenvcnt+1+1)*sizeof(*envp)));
else
newenv = (char **)realloc((char *)newenv, (unsigned)((oldenvcnt+1+1)*sizeof(*envp)));
if (newenv == NULL)
return FAILED;
/* copy old environment pointers, add var, switch environments */
(void) bcopy((char *)environ, (char *)newenv, oldenvcnt*sizeof(*envp));
newenv[oldenvcnt] = var;
newenv[oldenvcnt+1] = NULL;
environ = newenv;
return WORKED;
}
#endif /* NO_PUTENV */
#else
/* OpenVMS has no putenv() function. So we'll make one ;-) */
/* peculiar return values */
#define WORKED 0
#define FAILED 1
int
putenv(var) /* put var in the environment */
char *var;
{ /* If there is a : imbedded in the variable name, then the text
prefixing that : is the logical name table where we want this
logical, and the text after it is the logical name; otherwise it's
to be defined as a symbol; if the table name is null, the
LNM$PROCESS table is assumed. A null value says to delete the
logical or symbol instead of set it.
*/
#include <ctype.h>
#include <descrip.h>
#include <ssdef.h>
#include <libdef.h>
#include <libclidef.h>
#include <lnmdef.h>
#include <psldef.h>
char *s;
$DESCRIPTOR(dsc$var,NULL);
$DESCRIPTOR(dsc$val,NULL);
$DESCRIPTOR(dsc$tbl,NULL);
int i;
unsigned char x;
long global = LIB$K_CLI_GLOBAL_SYM;
char *value = strchr(var,'=');
struct {
unsigned short int length;
unsigned short int code;
char *bufadr;
int *retlen;
} itmlst[2] = { { 0, LNM$_STRING, NULL, NULL},
{ 0, 0, 0, 0 } };
if (!value)
return(FAILED);
*(value++) = '\0';
if (s = strpbrk(var,":;")) { /* before : is LNM Table, after is logical */
x = (unsigned char)*s; /* mode -- :=super, ;=exec */
*(s++) = '\0';
dsc$var.dsc$a_pointer = s;
dsc$var.dsc$w_length = strlen(s);
if (strlen(var)) {
dsc$tbl.dsc$a_pointer = var;
dsc$tbl.dsc$w_length = strlen(var);
}
else {
dsc$tbl.dsc$a_pointer = NULL;
dsc$tbl.dsc$w_length = 0;
}
}
else { /* no : means var is a symbol */
dsc$var.dsc$a_pointer = var;
dsc$var.dsc$w_length = strlen(var);
dsc$tbl.dsc$a_pointer = NULL;
dsc$tbl.dsc$w_length = 0;
}
for (i=0, s = dsc$var.dsc$a_pointer; i < dsc$var.dsc$w_length; i++, s++)
*s = _toupper(*s);
if (!strlen(value)) { /* Hmmm... null value ought to mean delete */
if (dsc$tbl.dsc$w_length)
i = lib$delete_logical(&dsc$var, &dsc$tbl);
else
i = lib$delete_symbol(&dsc$var, &global);
if (i==LIB$_NOSUCHSYM || i==SS$_NOLOGNAM)
i = SS$_NORMAL;
}
else { /* non-null value means define var=value */
dsc$val.dsc$a_pointer = value;
dsc$val.dsc$w_length = strlen(value);
if (dsc$tbl.dsc$w_length) {
switch(x) {
case ':': i = lib$set_logical(&dsc$var, &dsc$val, &dsc$tbl);
break;
case ';': x = PSL$C_EXEC;
itmlst[0].bufadr = dsc$val.dsc$a_pointer;
itmlst[0].length = dsc$val.dsc$w_length;
i = sys$crelnm(NULL, &dsc$tbl, &dsc$var, &x, &itmlst);
break;
}
}
else
i = lib$set_symbol(&dsc$var, &dsc$val, &global);
}
vaxc$errno = i;
return(i==SS$_NORMAL?WORKED:FAILED);
}
#endif
#ifdef NO_FGETPWENT
struct passwd *
fgetpwent(f)
FILE *f;
{
static char input[256];
static struct passwd *p = NULL;
char *cp, *cp2;
if (p == NULL) {
p = (struct passwd *) malloc(sizeof(struct passwd));
}
if (fgets(input, 256, f) == NULL)
return(NULL);
/* Username */
cp = strchr(input, ':');
if (cp == NULL) return(NULL);
*cp = '\0'; cp++;
p->pw_name = input;
/* Password */
cp2 = strchr(cp, ':');
if (cp2 == NULL) return(NULL);
*cp2 = '\0'; cp2++;
p->pw_passwd = cp;
/* UID */
cp = strchr(cp2, ':');
if (cp == NULL) return(NULL);
*cp = '\0'; cp++;
p->pw_uid = atoi(cp2);
/* GID */
cp2 = strchr(cp, ':');
if (cp2 == NULL) return(NULL);
*cp2 = '\0'; cp2++;
p->pw_gid = atoi(cp);
/* GECOS */
cp = strchr(cp2, ':');
if (cp == NULL) return(NULL);
*cp = '\0'; cp++;
p->pw_gecos = cp2;
/* Home dir */
cp2 = strchr(cp, ':');
if (cp2 == NULL) return(NULL);
*cp2 = '\0'; cp2++;
p->pw_dir = cp;
/* Shell */
p->pw_shell = cp2;
return(p);
}
#endif /* NO_FGETPWENT */
#if defined(__VMS) && defined(MULTINET)
#if ( defined(CLIENT_LOGGER) || defined(TELNET_TRACE) || defined(VMS_SERVER))
/*
* JL Wilkinson 16-Jul-1994 Merged in TGV's syslog() functions to allow
* the CLIENT_LOGGER and TELNET_TRACE functionality to work with
* Multinet. Not tested against other VMS TCP/IP agents, and *NOT
* SUPPORTED* thru TGV -- please don't anybody ask TGV for help in using
* this. Somebody who wants to use it can Email me or the
*
[email protected] group and I'll try to assist them for
* MULTINET only (
[email protected]). Basic documentation is in
* the file [.doc]syslogd.vms. An implementation for UCX of SYSLOGD is
* apparently available, but so far this code has not been adapted to it.
*/
#include "syslog.h"
/*
* Copyright (C) 1992 TGV, Incorporated
*/
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char sccsid[] = "@(#)syslog.c 5.3 (Berkeley) 9/17/85";
#endif /* not lint */
/*
* SYSLOG -- print message on log file
*
* This routine looks a lot like printf, except that it
* outputs to the log file instead of the standard output.
* Also:
* adds a timestamp,
* prints the module name in front of the message,
* has some other formatting types (or will sometime),
* adds a newline on the end of the message.
*
* The output of this routine is intended to be read by /etc/syslogd.
*
* Author: Eric Allman
* Modified to use UNIX domain IPC by Ralph Campbell
*/
#include <stdio.h> /* JDB */
#include <lnmdef.h> /* JLW */
#include <ssdef.h> /* JLW */
#include <types.h>
#include <socket.h>
#include <file.h>
#include <signal.h>
#ifndef _sys_syslog_h
#include "syslog.h" /* was <syslog.h> -- JLW */
#endif
#include <netdb.h>
#ifdef __ALPHA
#include <varargs.h>
#endif /* __ALPHA */
#define MAXLINE 1024 /* max message size */
#define PRIMASK(p) (1 << ((p) & LOG_PRIMASK))
#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
#define IMPORTANT LOG_ERR
static char logname[] = "/dev/log";
static char ctty[] = "/dev/console";
static int LogFile = -1; /* fd for log */
static int LogStat = 0; /* status bits, set by openlog() */
static char *LogTag = "syslog"; /* string to tag the entry with */
static int LogMask = 0xff; /* mask of priorities to be logged */
static int LogFacility = LOG_USER; /* default facility code */
static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
#ifdef ORIG
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
#endif
char *vms_errno_string();
#ifdef __ALPHA
syslog(va_alist)
va_dcl
#else /* __ALPHA */
syslog(pri, fmt, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)
int pri;
char *fmt;
#endif /* __ALPHA */
{
char buf[MAXLINE + 1], outline[MAXLINE + 1];
register char *b, *f, *o;
register int c;
long now;
int pid;
#ifdef ORIG
int pid, olderrno = errno;
#endif
#ifdef __ALPHA
int pri, numargs;
char *fmt;
__int64 p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
va_list ap;
va_start(ap);
va_count(numargs);
pri = va_arg(ap, int);
fmt = va_arg(ap, char *);
if (numargs > 2) p0 = va_arg(ap, __int64);
if (numargs > 3) p1 = va_arg(ap, __int64);
if (numargs > 4) p2 = va_arg(ap, __int64);
if (numargs > 5) p3 = va_arg(ap, __int64);
if (numargs > 6) p4 = va_arg(ap, __int64);
if (numargs > 7) p5 = va_arg(ap, __int64);
if (numargs > 8) p6 = va_arg(ap, __int64);
if (numargs > 9) p7 = va_arg(ap, __int64);
if (numargs > 10) p8 = va_arg(ap, __int64);
if (numargs > 11) p9 = va_arg(ap, __int64);
#endif /* __ALPHA */
/* see if we should just throw out this message */
if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0)
return;
if (LogFile < 0)
openlog(LogTag, LogStat & ~LOG_ODELAY, 0);
/* set default facility if none specified */
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
/* build the message */
o = outline;
sprintf(o, "<%d>", pri);
o += strlen(o);
time(&now);
sprintf(o, "%.15s ", ctime(&now) + 4);
o += strlen(o);
if (LogTag && strcmp(LogTag, "dprintf")) {
strcpy(o, LogTag);
o += strlen(o);
}
if (LogStat & LOG_PID) {
sprintf(o, "[Pid 0x%x]", getpid());
o += strlen(o);
}
if (LogTag && strcmp(LogTag, "dprintf")) {
strcpy(o, ": ");
o += 2;
}
b = buf;
f = fmt;
while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
if (c != '%') {
*b++ = c;
continue;
}
if ((c = *f++) != 'm') {
*b++ = '%';
*b++ = c;
continue;
}
sprintf(b, "%s", vms_errno_string() );
b += strlen(b);
}
*b++ = '\n';
*b = '\0';
sprintf(o, buf, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
c = strlen(outline);
if (c > MAXLINE)
c = MAXLINE;
/* output the message to the local logger */
#ifndef VMS$TrnLNM
if (getenv("MULTINET_SYSLOG_DESTINATION") != NULL)
#else
if (VMS$TrnLNM("MULTINET_SYSLOG_DESTINATION",0)
#endif
{
if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) {
return 1;
}
}
#ifdef Send_Oper
if (!(LogStat & LOG_CONS) && (pri & LOG_PRIMASK) <= LOG_ERR)
return -1;
/* Output the message to the console, add the LogTag so it looks
* like syslog(), even if syslog is disabled and we're using OPCOM.
* make sure there is a newline.
*/
o = outline;
if (LogTag && strcmp(LogTag, "dprintf")) {
strcpy(o, LogTag);
o += strlen(o);
*o++ = ':';
*o++ = ' ';
}
sprintf(o, fmt, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
c = strlen(outline);
if (c > MAXLINE)
c = MAXLINE-1;
if ( outline[c-1] != '\n' ) {
outline[c] = '\n';
outline[c+1] = '\0';
}
Send_Oper(outline);
#endif
return 1;
}
/*
* OPENLOG -- open system log
*/
openlog(ident, logstat, logfac)
char *ident;
int logstat, logfac;
{
if (ident != NULL)
LogTag = ident;
LogStat = logstat;
if (logfac != 0)
LogFacility = logfac & LOG_FACMASK;
if (LogFile >= 0)
return;
SyslogAddr.sa_family = AF_UNIX;
strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
if (!(LogStat & LOG_ODELAY)) {
LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
#ifdef ORIG
fcntl(LogFile, F_SETFD, 1);
#endif
}
}
/*
* CLOSELOG -- close the system log
*/
closelog()
{
(void) close(LogFile);
LogFile = -1;
}
/*
* SETLOGMASK -- set the log mask level
*/
setlogmask(pmask)
int pmask;
{
int omask;
omask = LogMask;
if (pmask != 0)
LogMask = pmask;
return (omask);
}
#endif
#endif