
/*
 *         PVM version 3.3:  Parallel Virtual Machine System
 *               University of Tennessee, Knoxville TN.
 *           Oak Ridge National Laboratory, Oak Ridge TN.
 *                   Emory University, Atlanta GA.
 *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
 *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
 *                   (C) 1992 All Rights Reserved
 *
 *                              NOTICE
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted
 * provided that the above copyright notice appear in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * Neither the Institutions (Emory University, Oak Ridge National
 * Laboratory, and University of Tennessee) nor the Authors make any
 * representations about the suitability of this software for any
 * purpose.  This software is provided ``as is'' without express or
 * implied warranty.
 *
 * PVM version 3 was funded in part by the U.S. Department of Energy,
 * the National Science Foundation and the State of Tennessee.
 */

/*
 *	pvmlog.c
 *
 *	Error logging fac.
 *
$Log: pvmlog.c,v $
 * Revision 1.4  1994/06/03  20:38:25  manchek
 * version 3.3.0
 *
 * Revision 1.3  1993/11/30  15:53:59  manchek
 * added timestamp option
 *
 * Revision 1.2  1993/10/04  20:31:21  manchek
 * renamed useruid to pvm_useruid for compat with libpvm.
 * added alternate logfile name if SHAREDTMP is defined
 *
 * Revision 1.1  1993/08/30  23:26:51  manchek
 * Initial revision
 *
 */

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <time.h>
#include <fcntl.h>
#ifdef	SYSVSTR
#include <string.h>
#define	CINDEX(s,c)	strchr(s,c)
#else
#include <strings.h>
#define	CINDEX(s,c)	index(s,c)
#endif

#ifndef PVMDLOGMAX
#define PVMDLOGMAX 1000000			/* (approx) max chars to log to file */
#endif

#ifdef	SHAREDTMP
#define	PVMDLOGFILE	"/tmp/pvml.%d.%s"	/* log file name */
#else
#define	PVMDLOGFILE	"/tmp/pvml.%d"	/* log file name */
#endif


/***************
 **  Globals  **
 **           **
 ***************/

extern int errno;					/* from libc */
extern int sys_nerr;
extern char *sys_errlist[];

extern int mytid;					/* from pvmd.c */
extern int myunixpid;				/* from pvmd.c */
extern int pvm_useruid;				/* from pvmd.c */

int log_fd = -1;					/* error log file */
int log_how = 1;					/* how much error logging we can do */


/***************
 **  Private  **
 **           **
 ***************/

static char rcsid[] = "$Id: pvmlog.c,v 1.4 1994/06/03 20:38:25 manchek Exp $";
static char pvmtxt[2048];			/* scratch for error log */


/*	pvmlogerror()
*
*	Log an error message.  Effect depends on how far we've gotten.
*	If log_how & 1, write to stderr.
*	If log_how & 2, can write to the logfile.
*	If log_how & 4, can send message to console pvmd.
*/

pvmlogerror(s)
	char *s;	/* text */
{
	static char *toomuch = "\n*** logging truncated\n";
	static int log_alrdy = 0;		/* how much already written to file */
	int len = strlen(s);
	char buf[40];
	int l;
#ifdef	TIMESTAMPLOG
	time_t now;
	struct tm *tmp;

	time(&now);
	tmp = localtime(&now);
#endif	/*TIMESTAMPLOG*/

	if (log_how & 1) {
#ifdef	TIMESTAMPLOG
		if (mytid)
			fprintf(stderr, "[t%x] %02d/%02d %02d:%02d:%02d %s", mytid,
					tmp->tm_mon + 1,
					tmp->tm_mday,
					tmp->tm_hour,
					tmp->tm_min,
					tmp->tm_sec,
					s);
		else
			fprintf(stderr, "[pvmd pid%d] %02d/%02d %02d:%02d:%02d %s", myunixpid,
					tmp->tm_mon + 1,
					tmp->tm_mday,
					tmp->tm_hour,
					tmp->tm_min,
					tmp->tm_sec,
					s);

#else	/*TIMESTAMPLOG*/
		if (mytid)
			fprintf(stderr, "[t%x] %s", mytid, s);
		else
			fprintf(stderr, "[pvmd pid%d] %s", myunixpid, s);
#endif	/*TIMESTAMPLOG*/
	}

	if (log_how & 2) {
		if (log_alrdy < PVMDLOGMAX) {
#ifdef	TIMESTAMPLOG
			if (mytid)
				sprintf(buf, "[t%x] %02d/%02d %02d:%02d:%02d ", mytid,
						tmp->tm_mon + 1,
						tmp->tm_mday,
						tmp->tm_hour,
						tmp->tm_min,
						tmp->tm_sec);
			else
				sprintf(buf, "[pvmd pid%d] %02d/%02d %02d:%02d:%02d ", myunixpid,
						tmp->tm_mon + 1,
						tmp->tm_mday,
						tmp->tm_hour,
						tmp->tm_min,
						tmp->tm_sec);

#else	/*TIMESTAMPLOG*/
			if (mytid)
				sprintf(buf, "[t%x] ", mytid);
			else
				sprintf(buf, "[pvmd pid%d] ", myunixpid);
#endif	/*TIMESTAMPLOG*/

			l = strlen(buf);
			(void)write(log_fd, buf, l);
			(void)write(log_fd, s, len);
			if ((log_alrdy += len + l) >= PVMDLOGMAX)
				(void)write(log_fd, toomuch, strlen(toomuch));
		}
	}

/*
	if ((log_how & 4) && hosts->ht_local != hosts->ht_cons) {
XXX send error-log message to console host
	}
*/
}


pvmlogperror(s)
	char *s;	/* text */
{
	(void)sprintf(pvmtxt, "%s: %s\n", s,
		((errno >= 0 && errno < sys_nerr)
		? sys_errlist[errno] : "Unknown Error"));
	pvmlogerror(pvmtxt);
}


pvmlogopen()
{
	char buf[160];
	char hna[128];
	char *p;

	if (!(log_how & 2)) {
#ifdef	SHAREDTMP
		if (gethostname(hna, sizeof(hna)-1) == -1) {
			pvmlogerror("pvmlogopen() can't gethostname()\n");
			return 0;
		}
		if (p = CINDEX(hna, '.'))
			*p = 0;
		(void)sprintf(buf, PVMDLOGFILE, pvm_useruid, hna);
#else
		(void)sprintf(buf, PVMDLOGFILE, pvm_useruid);
#endif
		if ((log_fd = open(buf, O_WRONLY|O_TRUNC|O_CREAT|O_APPEND, 0600)) != -1)
			log_how |= 2;
	}
}


