char LogPath[100]; FILE *hLog; int LogDirty; DWORD LogTick; void LogReOpen (void) { hLog = fopen(LogPath, "ab"); if (hLog == NULL) { fprintf(stderr, "Open failed: %s\n", LogPath); exit(1); } LogDirty = 0; LogTick = GetTickCount(); return; } // // Get next log sequence number. This is found // in the file \seq.txt -- which is created if // not present. // int NextSequence (void) { FILE *f; char *Path = "\\seq.txt"; long Value; f = fopen(Path, "r"); if (f == NULL) { Value = 1; } else { fscanf(f, "%ld", &Value); fclose(f); } f = fopen(Path, "w"); fprintf(f, "%ld", Value + 1); fclose(f); return Value; } BOOL WINAPI CtrlHandler (DWORD CtrlType); void LogOpen (char *Path) { long LogNumber; if (strstr(Path, "%d") != NULL) { LogNumber = NextSequence(); sprintf(LogPath, Path, LogNumber); } else if (Path == NULL) { LogNumber = NextSequence(); sprintf(LogPath, "log%d.txt", LogNumber); } else { strcpy(LogPath, Path); } fprintf(stderr, "** Opening file %s\n", LogPath); LogReOpen(); SetConsoleCtrlHandler(CtrlHandler, TRUE); return; } void LogClose (void) { fprintf(stderr, "** Closing %s\n", LogPath); fclose(hLog); return; } // // Close and re-open the log file to guarantee // the data has been flushed to disk. // #define SYNC_SECONDS 15 void LogSync (void) { if (LogDirty) { if (GetTickCount() - LogTick > (SYNC_SECONDS * 1000)) { fclose(hLog); DEBUG printf("[checkpoint]\n"); LogReOpen(); } } return; } void LogWrite (char *Buffer, DWORD Size) { if (Size != 0) { fwrite(Buffer, Size, 1, stdout); fflush(stdout); if (fwrite(Buffer, Size, 1, hLog) != 1) { fprintf(stderr, "Log file fwrite error - ignoring!\n"); // exit(1); } fflush(hLog); LogDirty = 1; } LogSync(); return; } // // Return Modified Julian Day (MJD) given // calendar year, month (1-12), and day (1-31). // - Valid for Gregorian dates from 17-Nov-1858. // - Adapted from sci.astro FAQ. // long _DateToMjd (long Year, long Month, long Day) { return 367 * Year - 7 * (Year + (Month + 9) / 12) / 4 - 3 * ((Year + (Month - 9) / 7) / 100 + 1) / 4 + 275 * Month / 9 + Day + 1721028 - 2400000; } // // Generate sequence number, MJD, and/or UTC time stamp. // char *LogTimeStamp (int type) { static char buf[100]; // STATIC static long Sequence = 0; char ms[10]; char *p; SYSTEMTIME St; GetSystemTime(&St); buf[0] = '\0'; p = buf; // // Display line sequence number. // if (type & TS_SEQ) { Sequence += 1; p += sprintf(p, "%ld ", Sequence); } // // Display Modified Julian Date. // if (type & TS_MJD) { long Mjd, Seconds; Mjd = _DateToMjd(St.wYear, St.wMonth, St.wDay); Seconds = (((St.wHour * 60) + St.wMinute) * 60) + St.wSecond; p += sprintf(p, "%.6lf ", Mjd + Seconds / 86400.0); } // // Display UTC date and time (and milliseconds). // ms[0] = '\0'; if (type & TS_MS) { sprintf(ms, ".%.3ld", St.wMilliseconds); } if (type & (TS_UTC | TS_MS)) { p += sprintf(p, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d%s ", St.wYear, St.wMonth, St.wDay, St.wHour, St.wMinute, St.wSecond, ms); } return buf; // STATIC } // // Flush log file on ctrl-c exit. // BOOL WINAPI CtrlHandler (DWORD CtrlType) { if (CtrlType == CTRL_C_EVENT) { LogClose(); #ifdef COMM_CLOSE CommClose(); #endif exit(0); } return TRUE; }