00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "opensync.h"
00022 #include "opensync_internals.h"
00023 #include <pthread.h>
00024 GPrivate* current_tabs = NULL;
00032
00035 void osync_trace_reset_indent(void)
00036 {
00037 g_private_set(current_tabs, GINT_TO_POINTER(0));
00038 }
00039
00040
00051 void osync_trace(OSyncTraceType type, const char *message, ...)
00052 {
00053 #if defined ENABLE_TRACE
00054
00055 va_list arglist;
00056 char *buffer = NULL;
00057
00058 const char *trace = g_getenv("OSYNC_TRACE");
00059 const char *sensitive = g_getenv("OSYNC_PRIVACY");
00060
00061
00062 if (!trace)
00063 return;
00064
00065 if (!g_file_test(trace, G_FILE_TEST_IS_DIR)) {
00066 printf("OSYNC_TRACE argument is no directory\n");
00067 return;
00068 }
00069
00070 if (!g_thread_supported ()) g_thread_init (NULL);
00071 int tabs = 0;
00072
00073 if (!current_tabs)
00074 current_tabs = g_private_new (NULL);
00075 else
00076 tabs = GPOINTER_TO_INT(g_private_get(current_tabs));
00077
00078 unsigned long int id = (unsigned long int)pthread_self();
00079 pid_t pid = getpid();
00080 char *logfile = g_strdup_printf("%s/Thread%lu-%i.log", trace, id, (int)pid);
00081
00082 va_start(arglist, message);
00083 buffer = g_strdup_vprintf(message, arglist);
00084
00085 GString *tabstr = g_string_new("");
00086 int i = 0;
00087 for (i = 0; i < tabs; i++) {
00088 tabstr = g_string_append(tabstr, "\t");
00089 }
00090
00091 GTimeVal curtime;
00092 g_get_current_time(&curtime);
00093 char *logmessage = NULL;
00094 switch (type) {
00095 case TRACE_ENTRY:
00096 logmessage = g_strdup_printf("[%li.%li]\t%s>>>>>>> %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00097 tabs++;
00098 break;
00099 case TRACE_INTERNAL:
00100 logmessage = g_strdup_printf("[%li.%li]\t%s%s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00101 break;
00102 case TRACE_SENSITIVE:
00103 if (!sensitive)
00104 logmessage = g_strdup_printf("[%li.%li]\t%s[SENSITIVE] %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00105 else
00106 logmessage = g_strdup_printf("[%li.%li]\t%s[SENSITIVE CONTENT HIDDEN]\n", curtime.tv_sec, curtime.tv_usec, tabstr->str);
00107 break;
00108 case TRACE_EXIT:
00109 logmessage = g_strdup_printf("[%li.%li]%s<<<<<<< %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00110 tabs--;
00111 if (tabs < 0)
00112 tabs = 0;
00113 break;
00114 case TRACE_EXIT_ERROR:
00115 logmessage = g_strdup_printf("[%li.%li]%s<--- ERROR --- %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00116 tabs--;
00117 if (tabs < 0)
00118 tabs = 0;
00119 break;
00120 case TRACE_ERROR:
00121 logmessage = g_strdup_printf("[%li.%li]%sERROR: %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
00122 break;
00123 }
00124 g_free(buffer);
00125 g_private_set(current_tabs, GINT_TO_POINTER(tabs));
00126 va_end(arglist);
00127
00128 g_string_free(tabstr, TRUE);
00129
00130 GError *error = NULL;
00131 GIOChannel *chan = g_io_channel_new_file(logfile, "a", &error);
00132 if (!chan) {
00133 printf("unable to open %s for writing: %s\n", logfile, error->message);
00134 return;
00135 }
00136
00137 gsize writen;
00138 g_io_channel_set_encoding(chan, NULL, NULL);
00139 if (g_io_channel_write_chars(chan, logmessage, strlen(logmessage), &writen, NULL) != G_IO_STATUS_NORMAL) {
00140 printf("unable to write trace to %s\n", logfile);
00141 } else
00142 g_io_channel_flush(chan, NULL);
00143
00144 g_io_channel_shutdown(chan, TRUE, NULL);
00145 g_io_channel_unref(chan);
00146 g_free(logmessage);
00147 g_free(logfile);
00148
00149 #endif
00150 }
00151
00161 void osync_debug(const char *subpart, int level, const char *message, ...)
00162 {
00163 #if defined ENABLE_DEBUG
00164 osync_assert_msg(level <= 4 && level >= 0, "The debug level must be between 0 and 4.");
00165 va_list arglist;
00166 char buffer[1024];
00167 memset(buffer, 0, sizeof(buffer));
00168 int debug = -1;
00169
00170 va_start(arglist, message);
00171 g_vsnprintf(buffer, 1024, message, arglist);
00172
00173 char *debugstr = NULL;
00174 switch (level) {
00175 case 0:
00176
00177 debugstr = g_strdup_printf("[%s] ERROR: %s", subpart, buffer);
00178 break;
00179 case 1:
00180
00181 debugstr = g_strdup_printf("[%s] WARNING: %s", subpart, buffer);
00182 break;
00183 case 2:
00184
00185 debugstr = g_strdup_printf("[%s] INFORMATION: %s", subpart, buffer);
00186 break;
00187 case 3:
00188
00189 debugstr = g_strdup_printf("[%s] DEBUG: %s", subpart, buffer);
00190 break;
00191 case 4:
00192
00193 debugstr = g_strdup_printf("[%s] FULL DEBUG: %s", subpart, buffer);
00194 break;
00195 }
00196 g_assert(debugstr);
00197 va_end(arglist);
00198
00199 osync_trace(TRACE_INTERNAL, debugstr);
00200
00201 const char *dbgstr = g_getenv("OSYNC_DEBUG");
00202 if (dbgstr) {
00203 debug = atoi(dbgstr);
00204 if (debug >= level)
00205 printf("%s\n", debugstr);
00206 }
00207
00208 g_free(debugstr);
00209 #endif
00210 }
00211
00220 char *osync_print_binary(const unsigned char *data, int len)
00221 {
00222 int t;
00223 GString *str = g_string_new("");
00224 for (t = 0; t < len; t++) {
00225 if (data[t] >= ' ' && data[t] <= 'z')
00226 g_string_append_c(str, data[t]);
00227 else
00228 g_string_append_printf(str, " %02x ", data[t]);
00229 }
00230 return g_string_free(str, FALSE);
00231 }
00232
00241 char *osync_rand_str(int maxlength)
00242 {
00243 char *randchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ1234567890";
00244
00245 int length;
00246 char *retchar;
00247 int i = 0;
00248
00249 length = g_random_int_range(1, maxlength + 1);
00250 retchar = malloc(length * sizeof(char) + 1);
00251 retchar[0] = 0;
00252
00253 for (i = 0; i < length; i++) {
00254 retchar[i] = randchars[g_random_int_range(0, strlen(randchars))];
00255 retchar[i + 1] = 0;
00256 }
00257
00258 return retchar;
00259 }
00260