1 // ----------------------------------------------------------------------------
2 // log.cxx -- Received text logging for fldigi
3 //
4 // Copyright (C) 2007-2008
5 // Dave Freese, W1HKJ
6 //
7 // This file is part of fldigi.
8 //
9 // Fldigi is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // Fldigi is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
21 // ----------------------------------------------------------------------------
22
23
24 #include <config.h>
25
26 #ifdef __MINGW32__
27 # include "compat.h"
28 #endif
29
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <stdio.h>
34 #include <sys/time.h>
35 #include <string>
36 #include <cstring>
37
38 #include "log.h"
39 #include "trx.h"
40 #include "fl_digi.h"
41 #include "timeops.h"
42
43 #include "ascii.h"
44
45 using namespace std;
46
47 static const char *lognames[] = { "RX", "TX", "", "" };
48
cLogfile(const string & fname)49 cLogfile::cLogfile(const string& fname)
50 : retflag(true), logtype(LOG_RX)
51 {
52 if ((logfile = fl_fopen(fname.c_str(), "a"))) {
53 setvbuf(logfile, (char*)NULL, _IOLBF, 0);
54 set_cloexec(fileno(logfile), 1);
55 }
56 }
57
~cLogfile()58 cLogfile::~cLogfile()
59 {
60 if (logfile)
61 fclose(logfile);
62 }
63
log_to_file(log_t type,const string & s)64 void cLogfile::log_to_file(log_t type, const string& s)
65 {
66 if (!logfile || ferror(logfile) || s.empty())
67 return;
68
69 char timestr[64];
70 struct tm tm;
71 time_t t;
72
73 if (type == LOG_RX || type == LOG_TX) {
74 if (retflag || type != logtype) {
75 if (type != logtype) fprintf(logfile, "\n");
76 time(&t);
77 gmtime_r(&t, &tm);
78 strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%MZ", &tm);
79 char freq[20];
80 snprintf(freq, sizeof(freq), "%d",
81 static_cast<int>( wf->rfcarrier() +
82 (wf->USB() ? active_modem->get_freq()
83 : -active_modem->get_freq() ) ) );
84 const char *logmode = mode_info[active_modem->get_mode()].adif_name;
85
86 fprintf(logfile, "%s %s : %s (%s): ", lognames[type], freq, logmode, timestr);
87 }
88 for (size_t i = 0; i < s.length(); i++)
89 fprintf(logfile, "%s", ascii3[s[i] & 0xFF]);
90 // if (s[i] == '\n' || (unsigned char)s[i] >= ' ') fprintf(logfile, "%c", s[i]);
91 retflag = *s.rbegin() == '\n';
92 if (!retflag)
93 fflush(logfile);
94 }
95 else {
96 time(&t);
97 gmtime_r(&t, &tm);
98 // Was %e (space padded month) but it's not available in the MS C
99 // runtime library, %d (zero-padded) is more portable.
100 strftime(timestr, sizeof(timestr), "%a %b %d %H:%M:%S %Y UTC", &tm);
101 fprintf(logfile, "\n--- Logging %s at %s ---\n", s.c_str(), timestr);
102 }
103
104 logtype = type;
105 }
106
107
108
log_to_file_start()109 void cLogfile::log_to_file_start()
110 {
111 log_to_file(LOG_START, "started");
112 }
113
log_to_file_stop()114 void cLogfile::log_to_file_stop()
115 {
116 log_to_file(LOG_STOP, "stopped");
117 }
118
119
120
121 /* ---------------------------------------------------------------------- */
122
123