/**************************************************************************
*** COPYRIGHT (c) 2002 by TransNexus, Inc. ***
*** ***
*** This software is property of TransNexus, Inc. ***
*** This software is freely available under license from TransNexus. ***
*** The license terms and conditions for free use of this software by ***
*** third parties are defined in the OSP Toolkit Software License ***
*** Agreement (LICENSE.txt). Any use of this software by third ***
*** parties, which does not comply with the terms and conditions of the ***
*** OSP Toolkit Software License Agreement is prohibited without ***
*** the prior, express, written consent of TransNexus, Inc. ***
*** ***
*** Thank you for using the OSP ToolKit(TM). Please report any bugs, ***
*** suggestions or feedback to support@transnexus.com ***
*** ***
**************************************************************************/
/*
* Copyright (c) 1993 Addison-Wesley Publishing Company.
* All rights reserved. This source code is provided
* for its instructional value, and is not guaranteed
* for any particular purpose.
*/
#include "osp/osptnlog.h"
#ifndef _WIN32
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <grp.h>
#include <malloc.h>
#ifdef OSPTNLOGDEBUG
static char buf[BUFSZ];
static char tmpbuf[BUFSZ];
static int logfd = -1;
void get_log_time(char *timebuf)
{
time_t t;
char *tm;
time(&t);
tm = ctime(&t);
tm[19] = '\0';
sprintf(timebuf, "%s %ld", &tm[4], getpid());
timebuf[15] = '\0';
}
void
tnlog(char *fmt, ...)
{
va_list ap;
get_log_time(buf);
/*
* Append the caller's string to the buffer.
*/
va_start(ap, fmt);
vsprintf(tmpbuf, fmt, ap);
va_end(ap);
strcat(buf, tmpbuf);
if (!isspace(tmpbuf[0]))
{
sprintf( tmpbuf, "\n%s", buf);
strcpy(buf, tmpbuf);
}
/*
* Add a newline.
*/
strcat(buf, "\n");
/*
* Write the log message.
*/
write(logfd, buf, strlen(buf));
}
int
tnlogdump(unsigned char *data, int len, char *msg)
{
int i ;
int cnt=0;
unsigned char c;
int j=0;
char hexbuf[(DUMPLEN*3)+5];
char txtbuf[(DUMPLEN) + 5];
/*
* Preprocessing before new dump
*/
memset(hexbuf, (char) 0, sizeof(hexbuf));
memset(txtbuf, (char) 0, sizeof(hexbuf));
if (len)
{
/*
* Change newline to space. 24 is location
* of newline. 25 is end of string. Then
* copy the string to the buffer.
*/
get_log_time((char *)tmpbuf);
sprintf( buf, "\n%s", tmpbuf);
sprintf(tmpbuf, "LOGDUMP - %s\n", msg);
strcat(buf, tmpbuf);
sprintf(tmpbuf, "LENGTH = %6d =========================================================", len);
strcat(buf, tmpbuf);
/*
* Add a newline.
*/
strcat(buf, "\n");
/*
* Write the log message.
*/
write(logfd, buf, strlen(buf));
}
/*
* Dump the available data
*/
for (i=0 ; ; i++, cnt++ )
{
if (i && !(i%DUMPLEN))
{
sprintf(buf, "%05d: %s %s\n", (((i-1)/DUMPLEN)*DUMPLEN), hexbuf, txtbuf);
write(logfd, buf, strlen(buf));
strcpy(hexbuf, "");
j=0;
txtbuf[j] = '\0';
if (i >= len) break;
}
c = (i < len)? data[i] : ' ';
if (isalnum(c) || (c == ' ') || ispunct(c))
{
txtbuf[j++] = c;
}
else
{
txtbuf[j++] = '.';
}
txtbuf[j] = '\0';
if (i < len)
{
sprintf( tmpbuf, "%02x ", (unsigned int) c );
}
else
{
sprintf( tmpbuf, " ");
}
strcat(hexbuf, tmpbuf);
}
/* Flush the log buffer. */
sprintf(buf, "%s %s\n", hexbuf, txtbuf);
strcat(buf, "=========================================================================\n\n");
write(logfd, buf, strlen(buf));
strcpy(hexbuf, "");
j=0;
txtbuf[j] = '\0';
return(cnt);
}
int
tninitlog(char *filename)
{
struct stat sbuf;
struct group *gp;
char logfile[100];
int fl;
/* Point to stderr for output if no logfile specification */
if ((filename == (char *)NULL) || (filename[0] == '\0'))
{
strcpy(logfile, "/dev/stdout");
}
else
{
strcpy(logfile, filename);
}
/*
* Open the log file, creating it if it isn't
* present.
*/
logfd = open(logfile, O_WRONLY|O_APPEND|O_CREAT,
LOGPERM);
if (logfd < 0)
return(-1);
/*
* If the log file is too large, truncate it to 0.
*/
if (fstat(logfd, &sbuf) == 0)
{
if (sbuf.st_size > MAXLOGSZ)
ftruncate(logfd, 0);
}
/*
* Set the close-on-exec flag.
*/
fl = fcntl(logfd, F_GETFD, 0);
if ((fl < 0) ||
(fcntl(logfd, F_SETFD, fl|FD_CLOEXEC) < 0))
{
close(logfd);
logfd = -1;
return(-1);
}
/*
* Get the group ID for group "daemon."
*/
gp = getgrnam("daemon");
if (gp == NULL)
{
close(logfd);
logfd = -1;
errno = EINVAL;
return(-1);
}
/*
* If the file isn't owned by the super-user or group
* daemon, change the file's user and group IDs.
*/
if (fstat(logfd, &sbuf) < 0)
{
close(logfd);
logfd = -1;
return(-1);
}
if ((sbuf.st_uid != 0) || (sbuf.st_gid != gp->gr_gid))
fchown(logfd, 0, gp->gr_gid);
return(0);
}
void tnlogmemuse(char *string)
{
struct mallinfo sMallInfo;
static struct mallinfo sOldMallInfo;
int total;
int oldtotal;
static int gtotal = 0;
static int testcount = 0;
sMallInfo = mallinfo();
if (!testcount)
{
memset(&sOldMallInfo, 0, sizeof(sOldMallInfo));
}
testcount ++;
total = sMallInfo.usmblks + sMallInfo.uordblks;
gtotal += total;
oldtotal = sOldMallInfo.usmblks + sOldMallInfo.uordblks;
tnlog("MEMUSE: (avg: %d)(chg: %7d)(%7ld + %7d = %7d) %-30.30s" ,
gtotal/testcount, total - oldtotal,
sMallInfo.usmblks, sMallInfo.uordblks, total, string);
sOldMallInfo = sMallInfo;
return;
}
#endif
#endif /* WIN32 */