#include #include #include #include #include #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, ""); 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, ""); 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); } } 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, ""); 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