1 /*******************************************************************************
2  *
3  * Copyright (c) 2004 Guillaume Cottenceau
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2, as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  ******************************************************************************/
19 
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <time.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <syslog.h>
31 
32 #include "tools.h"
33 #include "log.h"
34 #include "net.h"
35 
36 int output_type = OUTPUT_TYPE_INFO;
37 int debug_mode = FALSE;
38 
get_current_time(void)39 time_t get_current_time(void)
40 {
41     struct timeval now;
42     struct timezone tz;
43     gettimeofday(&now, &tz);
44     return now.tv_sec;
45 }
46 
get_current_time_exact(void)47 double get_current_time_exact(void)
48 {
49     struct timezone tz;
50     struct timeval now;
51     gettimeofday(&now, &tz);
52     return (double) now.tv_sec + now.tv_usec / 1e6;  // bad bad idea to use float as precision is not down to the seconds then
53 }
54 
55 char current_date[50];
get_current_date(void)56 char* get_current_date(void)
57 {
58     struct tm * lt;
59     char buf[50];
60     double time = get_current_time_exact();
61     time_t seconds = (time_t)time;
62     lt = localtime(&seconds);
63     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", lt);
64     snprintf(current_date, sizeof(current_date), "%s.%03d", buf, (int)(1000 * (time-seconds)));
65     return current_date;
66 }
67 
logging_init(int portnum)68 void logging_init(int portnum) {
69         openlog(asprintf_("fb-server[TCP%d]", portnum), LOG_PID, LOG_DAEMON);
70         if (output_type == OUTPUT_TYPE_DEBUG) {
71                 l0(OUTPUT_TYPE_INFO, "Starting log. Messages displayed: DEBUG, CONNECT, INFO, ERROR.");
72         } else if (output_type == OUTPUT_TYPE_CONNECT) {
73                 l0(OUTPUT_TYPE_INFO, "Starting log. Messages displayed: CONNECT, INFO, ERROR.");
74         } else if (output_type == OUTPUT_TYPE_INFO) {
75                 l0(OUTPUT_TYPE_INFO, "Starting log. Messages displayed: INFO, ERROR.");
76         }
77 }
78 
get_wanted_type(int wanted_output_type)79 char* get_wanted_type(int wanted_output_type)
80 {
81         return wanted_output_type == OUTPUT_TYPE_DEBUG ? "DEBUG"
82              : wanted_output_type == OUTPUT_TYPE_CONNECT ? "CONNECT"
83              : wanted_output_type == OUTPUT_TYPE_INFO ? "INFO"
84              : "ERROR";
85 }
86 
l_(int wanted_output_type,char * file,long line,const char * func,char * fmt,...)87 void l_(int wanted_output_type, char* file, long line, const char* func, char* fmt, ...)
88 {
89     char *msg;
90     va_list args;
91     if (output_type <= wanted_output_type) {
92             int level = 0;
93             va_start(args, fmt);
94             msg = vasprintf_(fmt, args); // segfault later if no more memory :)
95             va_end(args);
96             if (wanted_output_type == OUTPUT_TYPE_DEBUG) {
97                     level = LOG_DEBUG;
98             } else if (wanted_output_type == OUTPUT_TYPE_CONNECT) {
99                     level = LOG_NOTICE;
100             } else if (wanted_output_type == OUTPUT_TYPE_INFO) {
101                     level = LOG_INFO;
102             } else if (wanted_output_type == OUTPUT_TYPE_ERROR) {
103                     level = LOG_ERR;
104             }
105             if (debug_mode)
106                     fprintf(stderr, "[%s] %s %s:%ld(%s): %s\n", get_current_date(), get_wanted_type(wanted_output_type), file, line, func, msg);
107             else {
108                     if (output_type == OUTPUT_TYPE_DEBUG)
109                             syslog(level, "[%s] %s %s:%ld(%s): %s", get_current_date(), get_wanted_type(wanted_output_type), file, line, func, msg);
110                     else
111                             syslog(level, "%s %s", get_wanted_type(wanted_output_type), msg);
112             }
113             free(msg);
114     }
115 }
116 
117