00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022
00023 #include "opensync.h"
00024 #include "opensync_internals.h"
00025
00026 GPrivate* current_tabs = NULL;
00027 GPrivate* thread_id = NULL;
00028 GPrivate* trace_disabled = NULL;
00029 GPrivate* trace_sensitive = NULL;
00030 GPrivate* print_stderr = NULL;
00031 const char *trace = NULL;
00032
00033 #ifndef _WIN32
00034 #include <pthread.h>
00035 #endif
00036
00037 void osync_trace_reset_indent(void)
00038 {
00039 g_private_set(current_tabs, GINT_TO_POINTER(0));
00040 }
00041
00042 void osync_trace_disable(void)
00043 {
00044 if (!trace_disabled)
00045 trace_disabled = g_private_new (NULL);
00046
00047 g_private_set(trace_disabled, GINT_TO_POINTER(1));
00048 }
00049 void osync_trace_enable(void)
00050 {
00051 if (!trace_disabled)
00052 trace_disabled = g_private_new (NULL);
00053
00054 if (!trace)
00055 g_private_set(trace_disabled, GINT_TO_POINTER(1));
00056 else
00057 g_private_set(trace_disabled, GINT_TO_POINTER(0));
00058
00059 }
00060
00061 osync_bool osync_trace_is_enabled(void)
00062 {
00063 if (!trace_disabled || !g_private_get(trace_disabled))
00064 return TRUE;
00065
00066 return FALSE;
00067 }
00068
00069
00070 #ifdef OPENSYNC_TRACE
00071
00074 static void _osync_trace_init()
00075 {
00076 const char *noprivacy;
00077 const char *error;
00078 trace = g_getenv("OSYNC_TRACE");
00079 if (!trace)
00080 return;
00081
00082 noprivacy = g_getenv("OSYNC_NOPRIVACY");
00083 if (!trace_sensitive)
00084 trace_sensitive = g_private_new(NULL);
00085
00086 if (noprivacy)
00087 g_private_set(trace_sensitive, GINT_TO_POINTER(1));
00088 else
00089 g_private_set(trace_sensitive, GINT_TO_POINTER(0));
00090
00091 error = g_getenv("OSYNC_PRINTERROR");
00092 if (!print_stderr)
00093 print_stderr = g_private_new(NULL);
00094
00095 if (error)
00096 g_private_set(print_stderr, GINT_TO_POINTER(1));
00097 else
00098 g_private_set(print_stderr, GINT_TO_POINTER(0));
00099
00100 if (!g_file_test(trace, G_FILE_TEST_IS_DIR)) {
00101 printf("OSYNC_TRACE argument is no directory\n");
00102 return;
00103 }
00104 }
00105 #endif
00106
00107 void osync_trace(OSyncTraceType type, const char *message, ...)
00108 {
00109 #ifdef OPENSYNC_TRACE
00110 va_list arglist;
00111 char *buffer = NULL;
00112 int tabs = 0;
00113 unsigned long int id = 0;
00114 #ifdef _WIN32
00115 int pid = 0;
00116 char tmp_buf[1024];
00117 #else
00118 pid_t pid = 0;
00119 #endif
00120 char *logfile = NULL;
00121 GString *tabstr = NULL;
00122 int i = 0;
00123 GTimeVal curtime;
00124 char *logmessage = NULL;
00125 GError *error = NULL;
00126 GIOChannel *chan = NULL;
00127 gsize writen;
00128 const char *endline = NULL;
00129
00130 if (!g_thread_supported ()) g_thread_init (NULL);
00131
00132 if (!trace_disabled || !g_private_get(trace_disabled)) {
00133 _osync_trace_init();
00134 osync_trace_enable();
00135 }
00136
00137 if (GPOINTER_TO_INT(g_private_get(trace_disabled)))
00138 return;
00139
00140 if (!current_tabs)
00141 current_tabs = g_private_new (NULL);
00142 else
00143 tabs = GPOINTER_TO_INT(g_private_get(current_tabs));
00144
00145 #ifdef _WIN32
00146 if (!thread_id)
00147 thread_id = g_private_new (NULL);
00148 id = GPOINTER_TO_INT(thread_id);
00149 pid = _getpid();
00150 endline = "\r\n";
00151 #else
00152 id = (unsigned long int)pthread_self();
00153 pid = getpid();
00154 endline = "\n";
00155 #endif
00156 logfile = g_strdup_printf("%s%cThread%lu-%i.log", trace, G_DIR_SEPARATOR, id, pid);
00157
00158 va_start(arglist, message);
00159
00160 #ifdef _WIN32
00161 vsnprintf(tmp_buf, 1024, message, arglist);
00162 buffer = g_strdup(tmp_buf);
00163 #else
00164 buffer = g_strdup_vprintf(message, arglist);
00165 #endif
00166
00167 tabstr = g_string_new("");
00168 for (i = 0; i < tabs; i++) {
00169 tabstr = g_string_append(tabstr, "\t");
00170 }
00171
00172 g_get_current_time(&curtime);
00173 switch (type) {
00174 case TRACE_ENTRY:
00175 logmessage = g_strdup_printf("[%li.%06li]\t%s>>>>>>> %s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00176 tabs++;
00177 break;
00178 case TRACE_INTERNAL:
00179 logmessage = g_strdup_printf("[%li.%06li]\t%s%s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00180 break;
00181 case TRACE_SENSITIVE:
00182 if (GPOINTER_TO_INT(g_private_get(trace_sensitive)))
00183 logmessage = g_strdup_printf("[%li.%06li]\t%s[SENSITIVE] %s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00184 else
00185 logmessage = g_strdup_printf("[%li.%06li]\t%s[SENSITIVE CONTENT HIDDEN]%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, endline);
00186 break;
00187 case TRACE_EXIT:
00188 logmessage = g_strdup_printf("[%li.%06li]%s<<<<<<< %s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00189 tabs--;
00190 if (tabs < 0)
00191 tabs = 0;
00192 break;
00193 case TRACE_EXIT_ERROR:
00194 logmessage = g_strdup_printf("[%li.%06li]%s<--- ERROR --- %s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00195 tabs--;
00196 if (tabs < 0)
00197 tabs = 0;
00198
00199 if (print_stderr)
00200 fprintf(stderr, "EXIT_ERROR: %s\n", buffer);
00201 break;
00202 case TRACE_ERROR:
00203 logmessage = g_strdup_printf("[%li.%06li]%sERROR: %s%s", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer, endline);
00204
00205 if (print_stderr)
00206 fprintf(stderr, "ERROR: %s\n", buffer);
00207
00208 break;
00209 }
00210 g_free(buffer);
00211 g_private_set(current_tabs, GINT_TO_POINTER(tabs));
00212 va_end(arglist);
00213
00214 g_string_free(tabstr, TRUE);
00215
00216 chan = g_io_channel_new_file(logfile, "a", &error);
00217 if (!chan) {
00218 printf("unable to open %s for writing: %s\n", logfile, error->message);
00219 return;
00220 }
00221
00222 g_io_channel_set_encoding(chan, NULL, NULL);
00223 if (g_io_channel_write_chars(chan, logmessage, strlen(logmessage), &writen, NULL) != G_IO_STATUS_NORMAL) {
00224 printf("unable to write trace to %s\n", logfile);
00225 } else
00226 g_io_channel_flush(chan, NULL);
00227
00228 g_io_channel_shutdown(chan, TRUE, NULL);
00229 g_io_channel_unref(chan);
00230 g_free(logmessage);
00231 g_free(logfile);
00232
00233 #endif
00234 }
00235