/* * loglib.h * * A non-intrusive minimal log framework. * * History: * 14/03/2014 Creation * * Author: Dario Rodriguez dario@softhome.net * This file is licensed under the terms of the GNU LGPL v2+ */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <time.h> #include <stdarg.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "loglib.h" #define MAXLOGFILENAME 1024 #define LOGWRITEBUFSIZE 4096 #define LOGWRITEHEXDUMPSIZE 4096 #define DEFAULTFD 2 void log_write(char *type, char *format, ...) { static void (*writefunc)(int fd, char *buf, long bufsize, void *usrptr)=NULL; static void *usrptr=NULL; static int fd=DEFAULTFD; static char logfilename[MAXLOGFILENAME]={""}; static char writebuf[LOGWRITEBUFSIZE]; char *ptr; time_t t; struct tm stm; va_list arglist; /* if it is a special action, perform it */ if(type==((char *)log_setlogfile)) { if(fd!=DEFAULTFD) close(fd),fd=DEFAULTFD; strncpy(logfilename,format,sizeof(logfilename)-1); logfilename[sizeof(logfilename)-1]='\0'; return; } else if(type==((char *)log_closelogfile)) { if(fd!=DEFAULTFD) close(fd),fd=DEFAULTFD; return; } else if(type==((char *)log_setwritefunc)) { writefunc=(void (*)(int /*fd*/, char * /*buf*/, long /*bufsize*/, void */*usrptr*/)) format; va_start(arglist,format); usrptr=va_arg(arglist,void *); va_end(arglist); return; } /* it is a new log entry */ /* make sure the file is open */ if(fd==DEFAULTFD && logfilename[0]!='\0') { if((fd=open(logfilename,O_WRONLY|O_CREAT|O_APPEND,0640))==-1) { fd=DEFAULTFD; return; } } /* prepare the string */ t=time(NULL); localtime_r(&t,&stm); ptr=writebuf; strftime(ptr,writebuf+LOGWRITEBUFSIZE-ptr-1,"%b %e %H:%M:%S ",&stm); writebuf[LOGWRITEBUFSIZE-1]='\0'; ptr+=strlen(ptr); snprintf(ptr,writebuf+LOGWRITEBUFSIZE-ptr-1,"%s: ",type); writebuf[LOGWRITEBUFSIZE-1]='\0'; ptr+=strlen(ptr); va_start(arglist,format); vsnprintf(ptr,writebuf+LOGWRITEBUFSIZE-ptr-1,format,arglist); va_end(arglist); writebuf[LOGWRITEBUFSIZE-1]='\0'; ptr+=strlen(ptr); /* if the string is not terminated with a '\n', add the '\n' */ if(ptr>writebuf && ptr[-1]!='\n') { if(ptr<(writebuf+LOGWRITEBUFSIZE-1)) { *(ptr++)='\n'; *ptr='\0'; } else ptr[-1]='\n'; } /* commit the data */ if(writefunc!=NULL) writefunc(fd,writebuf,ptr-writebuf,usrptr); else write(fd,writebuf,ptr-writebuf); } char * log_hexdumpstr(char *data, long datasize) { static char hexdumpbuf[LOGWRITEHEXDUMPSIZE]; char c,*ptr; long i,l; l=(datasize>(LOGWRITEHEXDUMPSIZE/3))?(LOGWRITEHEXDUMPSIZE/3):datasize; for(i=0,ptr=hexdumpbuf;i<l;i++) { c=data[i]&0xf; *(ptr++)=(c<0xa)?c+'0':c+'a'-10; c=(data[i]>>4)&0xf; *(ptr++)=(c<0xa)?c+'0':c+'a'-10; *(ptr++)=' '; } ptr[(i>0)?i-1:0]='\0'; return(hexdumpbuf); } void log_setlogfile(char *filename) { log_write((char *)log_setlogfile,(char *)filename); } void log_closelogfile(void) { void *dummy=NULL; log_write((char *)log_closelogfile,(char *)dummy); } void log_setwritefunc(void (*newwritefunc)(int fd, char *buf, long bufsize, void *usrptr),void *usrptr) { log_write((char *)log_setwritefunc,(char *)newwritefunc,usrptr); }