Files
sicspsi/tecs/coc_logfile.c
cvs 064ec37e9a - Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module
- PSI specific stuff is now in the PSI directory.
- The old version has been tagged with pre-ansto
2003-06-20 10:18:47 +00:00

351 lines
7.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "coc_logfile.h"
#include "myc_time.h"
#include "myc_err.h"
#include "myc_str.h"
static FILE *fil=NULL;
static char lnam[224]="";
static char filnam[256]="";
static char ebuf[20000]="";
static char *statusBuf=NULL;
static int statusSize;
static char *eptr=&ebuf[0];
static int dated=0;
static int logMask=0;
static int wrtMask=0;
static int newLine=1;
static int logfileStd;
static int dirty, writeAll;
static int lastline=1;
static long int lastpos=0;
static int lastStamp=0;
static int openTime;
static int openDate;
void (*logfileOutRtn)(int, char *)=NULL;
void logfileOpen(int append) {
int year;
if (logfileStd) {
fil=stdout;
str_copy(filnam, "<stdout>");
return;
}
assert(fil==NULL);
openTime = mycNow();
openDate = mycDate(openTime); /* date in yyyymmdd decimal encoding */
openTime = openTime % (24*3600); /* seconds since midnight */
if (dated) {
sprintf(filnam, "%s%02d-%02d.log", lnam, openDate % 10000 / 100, openDate % 100);
} else {
if (lnam[0]=='\0') {
str_copy(filnam, "test.log");
} else {
str_copy(filnam, lnam);
str_append(filnam, ".log");
}
}
if (dated) {
fil=fopen(filnam, "a+");
if (fil != NULL) {
fseek(fil, 0, SEEK_SET); /* set position to start */
year=0;
fscanf(fil, "%4d", &year);
if (year != openDate / 10000) {
fclose(fil);
fil=fopen(filnam, "w+"); /* overwrite old logfile */
} else {
fseek(fil, 0, SEEK_END); /* set position to end */
}
}
} else {
fil=fopen(filnam, "w+"); /* overwrite last logfile */
}
if (fil==NULL) {
printf("Can not open %s\n", filnam);
fil=stdout;
str_copy(filnam, "<stdout>");
return;
}
ErrSetOutFile(fil);
fprintf(fil, "%04d-%02d-%02d %02d:%02d:%02d opened logfile\n"
, openDate / 10000, openDate % 10000 / 100, openDate % 100
, openTime / 3600, openTime / 60 % 60, openTime % 60);
lastStamp = openTime / 60;
}
void logfileStatusBuffer(char *buffer, int bufsize) {
statusBuf=buffer;
statusSize=bufsize-1;
}
char *logfileInit(char *path, int nodate, int use_stdout, int write_all) {
str_copy(lnam, path);
logfileStd=use_stdout;
writeAll=write_all;
dated=!nodate;
logfileOpen(1);
return(filnam);
}
void logfileStamp(char *text) {
int time, date, stamp;
time = mycNow();
date = mycDate(time); /* date in yyyymmdd decimal encoding */
time = time % (24*3600); /* seconds since midnight */
stamp=time / 60;
if (date != openDate ) { /* day has changed -> new logfile */
if (fil!=NULL) { fclose(fil); fil=NULL; }
lastpos=0;
lastline=1;
logfileOpen(1);
}
if (text==NULL) {
if (stamp>lastStamp+1) {
fprintf(fil, "---\t%02d:%02d:%02d\n", stamp / 60, stamp % 60, time % 60, text);
}
} else {
fprintf(fil, "\t%02d:%02d:%02d%s", stamp / 60, stamp % 60, time % 60, text);
}
dirty=0;
lastStamp=stamp;
}
void logfileOut(int mask, const char *fmt, ...)
{ va_list ap;
char buf[8192], *p;
int l;
va_start(ap, fmt);
if (mask & LOG_STAT && statusBuf!=NULL) {
if (newLine) {
statusBuf[0]='\0';
newLine=0;
}
buf[statusSize]='\0';
vsprintf(buf, fmt, ap);
assert(buf[statusSize]=='\0'); /* check for overflow */
if (buf[0]=='@') {
if (buf[1]==' ') {
str_ncat(statusBuf, buf+2, statusSize);
} else {
str_ncat(statusBuf, buf+1, statusSize);
}
} else {
str_ncat(statusBuf, buf, statusSize);
}
p=strchr(statusBuf, '\n');
if (p!=NULL) {
newLine=1;
*p='\0';
}
}
if (logfileOutRtn!=NULL) {
vsprintf(buf, fmt, ap); /* does not check for overflow! */
logfileOutRtn(mask, buf);
}
if (writeAll) {
vfprintf(fil, fmt, ap);
wrtMask=LOG_ALL;
} else if ((mask | LOG_NET) != LOG_NET) { /* do not store LOG_NET info */
if (eptr!=NULL) {
if (eptr-ebuf > sizeof(ebuf)-512) {
sprintf(eptr, "... buffer full ... \1\1");
eptr=NULL;
} else {
vsprintf(eptr, fmt, ap);
p=strchr(eptr, '\1');
if (p==NULL) {
l=strlen(eptr);
if (l>256) {
sprintf(buf, "unusual long output %.32s... (%d chars)\n", eptr, l);
logfileStamp(buf);
}
eptr+=l;
} else {
eptr=p; /* is in fact an error */
}
eptr[0]='\1'; /* put \1 as separator between blocks */
eptr[1]=mask & 31;
eptr[2]='\0';
eptr+=2;
}
}
wrtMask=wrtMask | mask;
}
va_end(ap);
}
void logfileMask(int mask) {
logMask=logMask | mask;
}
void logfileWrite0(int mask) {
char *s, *next;
logMask=logMask | mask;
if (dirty) logfileStamp(NULL); /* there was something written since last time */
s=ebuf;
if (writeAll || *s!='\0' && wrtMask & logMask) {
next=strchr(s, '\1');
while (next!=NULL) {
*next='\0';
next++;
if (*next & logMask) {
if (*s=='@') { /* write out time */
logfileStamp(s+1);
} else {
logfileStamp(NULL); /* write stamp before write something */
fprintf(fil, "%s", s);
dirty=1;
}
}
s=next+1;
next=strchr(s, '\1');
}
}
ebuf[0]='\0';
eptr=&ebuf[0];
logMask=0;
wrtMask=0;
}
void logfileScan(int date, void (*scanLine)(void*, char*), void *arg) {
FILE *sFile;
char buf[256], *res;
if (date == openDate) {
sFile=fil;
rewind(sFile);
} else {
sprintf(buf, "%s%02d-%02d.log", lnam, date % 10000 / 100, date % 100);
sFile=fopen(buf, "r+");
if (sFile==NULL) return;
}
res=fgets(buf, sizeof(buf), sFile);
while (res!=NULL) {
if (res[0]=='\t') {
scanLine(arg, res+1);
}
res=fgets(buf, sizeof(buf), sFile);
}
if (sFile==fil) {
fseek(fil, 0, SEEK_END);
} else {
fclose(sFile);
}
}
void logfileWrite(int mask) {
logfileWrite0(mask);
fflush(fil);
}
void logfileShowErr(char *text)
{
logfileWrite0(LOG_ALL); /* write all */
ErrShow(text);
fflush(fil);
}
void logfileClose()
{
logfileWrite0(LOG_MAIN+LOG_INFO);
lastStamp=-2;
logfileOut(LOG_MAIN, "closed\n");
logfileStamp(NULL);
if (fil!=NULL) { fclose(fil); fil=NULL; }
filnam[0]='\0';
}
void logfileOutBuf(int mask, StrBuf *buf)
{ char str[256];
int rd0;
char *ret;
rd0=buf->rdpos;
if (buf->rdpos < 0 || buf->rdpos >= buf->dsize
|| buf->wrpos < 0 || buf->wrpos >= buf->dsize) {
logfileOut(mask, "<buffer corrupt>"); return;
}
while (!StrEnd(buf)) {
ret=StrGet(buf, str, '\0');
if (ret==NULL) {
ret="...";
buf->rdpos=buf->wrpos;
}
if (ret[0]<32 && ret[0]>0) {
logfileOut(mask, "[%d]%s;", ret[0], ret+1);
} else {
logfileOut(mask, "%s;", ret);
}
}
buf->rdpos=rd0;
}
int logfileLength(void) {
char lin[256];
int l, ll;
if (logfileStd || fil==NULL) return 0;
fseek(fil, lastpos, SEEK_SET);
ll=lastpos;
l=lastline;
while (NULL!=fgets(lin, sizeof(lin), fil)) {
lastpos=ll;
ll=ftell(fil);
lastline=l;
l++;
}
return(lastline);
}
long int logfilePos(int n) {
/* set file to the start of n-th last line n, if n<0 then position to the -n-th line */
int i;
char lin[256];
if (logfileStd || fil==NULL) return 0;
if (n>0) {
n=logfileLength()-n+1;
} else {
n=-n;
}
fseek(fil, 0, SEEK_SET);
for (i=1; i<n; i++) {
if (NULL==fgets(lin, sizeof(lin), fil)) return ftell(fil);
}
return ftell(fil);
}
long int logfileGetLines(long int pos, int linmax, char *line, int len_line) {
int l,i;
if (logfileStd || fil==NULL) {
line[0]='\0';
return 0;
}
l=0;
fseek(fil, pos, SEEK_SET);
for (i=0; i<linmax; i++) {
if (NULL==fgets(line+l, len_line-l, fil)) {
line[l]='\0';
return ftell(fil);
}
l=strlen(line);
}
pos=ftell(fil);
fseek(fil, 0, SEEK_END);
return pos;
}