OpenSync  0.22
opensync_debug.c
1 /*
2  * libopensync - A synchronization framework
3  * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 
21 #include "opensync.h"
22 #include "opensync_internals.h"
23 #include <pthread.h>
24 GPrivate* current_tabs = NULL;
32 
36 {
37  g_private_set(current_tabs, GINT_TO_POINTER(0));
38 }
39 
40 
51 void osync_trace(OSyncTraceType type, const char *message, ...)
52 {
53 #if defined ENABLE_TRACE
54 
55  va_list arglist;
56  char *buffer = NULL;
57 
58  const char *trace = g_getenv("OSYNC_TRACE");
59  const char *sensitive = g_getenv("OSYNC_PRIVACY");
60 
61 
62  if (!trace)
63  return;
64 
65  if (!g_file_test(trace, G_FILE_TEST_IS_DIR)) {
66  printf("OSYNC_TRACE argument is no directory\n");
67  return;
68  }
69 
70  if (!g_thread_supported ()) g_thread_init (NULL);
71  int tabs = 0;
72 
73  if (!current_tabs)
74  current_tabs = g_private_new (NULL);
75  else
76  tabs = GPOINTER_TO_INT(g_private_get(current_tabs));
77 
78  unsigned long int id = (unsigned long int)pthread_self();
79  pid_t pid = getpid();
80  char *logfile = g_strdup_printf("%s/Thread%lu-%i.log", trace, id, (int)pid);
81 
82  va_start(arglist, message);
83  buffer = g_strdup_vprintf(message, arglist);
84 
85  GString *tabstr = g_string_new("");
86  int i = 0;
87  for (i = 0; i < tabs; i++) {
88  tabstr = g_string_append(tabstr, "\t");
89  }
90 
91  GTimeVal curtime;
92  g_get_current_time(&curtime);
93  char *logmessage = NULL;
94  switch (type) {
95  case TRACE_ENTRY:
96  logmessage = g_strdup_printf("[%li.%li]\t%s>>>>>>> %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
97  tabs++;
98  break;
99  case TRACE_INTERNAL:
100  logmessage = g_strdup_printf("[%li.%li]\t%s%s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
101  break;
102  case TRACE_SENSITIVE:
103  if (!sensitive)
104  logmessage = g_strdup_printf("[%li.%li]\t%s[SENSITIVE] %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
105  else
106  logmessage = g_strdup_printf("[%li.%li]\t%s[SENSITIVE CONTENT HIDDEN]\n", curtime.tv_sec, curtime.tv_usec, tabstr->str);
107  break;
108  case TRACE_EXIT:
109  logmessage = g_strdup_printf("[%li.%li]%s<<<<<<< %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
110  tabs--;
111  if (tabs < 0)
112  tabs = 0;
113  break;
114  case TRACE_EXIT_ERROR:
115  logmessage = g_strdup_printf("[%li.%li]%s<--- ERROR --- %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
116  tabs--;
117  if (tabs < 0)
118  tabs = 0;
119  break;
120  case TRACE_ERROR:
121  logmessage = g_strdup_printf("[%li.%li]%sERROR: %s\n", curtime.tv_sec, curtime.tv_usec, tabstr->str, buffer);
122  break;
123  }
124  g_free(buffer);
125  g_private_set(current_tabs, GINT_TO_POINTER(tabs));
126  va_end(arglist);
127 
128  g_string_free(tabstr, TRUE);
129 
130  GError *error = NULL;
131  GIOChannel *chan = g_io_channel_new_file(logfile, "a", &error);
132  if (!chan) {
133  printf("unable to open %s for writing: %s\n", logfile, error->message);
134  return;
135  }
136 
137  gsize writen;
138  g_io_channel_set_encoding(chan, NULL, NULL);
139  if (g_io_channel_write_chars(chan, logmessage, strlen(logmessage), &writen, NULL) != G_IO_STATUS_NORMAL) {
140  printf("unable to write trace to %s\n", logfile);
141  } else
142  g_io_channel_flush(chan, NULL);
143 
144  g_io_channel_shutdown(chan, TRUE, NULL);
145  g_io_channel_unref(chan);
146  g_free(logmessage);
147  g_free(logfile);
148 
149 #endif
150 }
151 
161 void osync_debug(const char *subpart, int level, const char *message, ...)
162 {
163 #if defined ENABLE_DEBUG
164  osync_assert_msg(level <= 4 && level >= 0, "The debug level must be between 0 and 4.");
165  va_list arglist;
166  char buffer[1024];
167  memset(buffer, 0, sizeof(buffer));
168  int debug = -1;
169 
170  va_start(arglist, message);
171  g_vsnprintf(buffer, 1024, message, arglist);
172 
173  char *debugstr = NULL;
174  switch (level) {
175  case 0:
176  //Error
177  debugstr = g_strdup_printf("[%s] ERROR: %s", subpart, buffer);
178  break;
179  case 1:
180  // Warning
181  debugstr = g_strdup_printf("[%s] WARNING: %s", subpart, buffer);
182  break;
183  case 2:
184  //Information
185  debugstr = g_strdup_printf("[%s] INFORMATION: %s", subpart, buffer);
186  break;
187  case 3:
188  //debug
189  debugstr = g_strdup_printf("[%s] DEBUG: %s", subpart, buffer);
190  break;
191  case 4:
192  //fulldebug
193  debugstr = g_strdup_printf("[%s] FULL DEBUG: %s", subpart, buffer);
194  break;
195  }
196  g_assert(debugstr);
197  va_end(arglist);
198 
199  osync_trace(TRACE_INTERNAL, debugstr);
200 
201  const char *dbgstr = g_getenv("OSYNC_DEBUG");
202  if (dbgstr) {
203  debug = atoi(dbgstr);
204  if (debug >= level)
205  printf("%s\n", debugstr);
206  }
207 
208  g_free(debugstr);
209 #endif
210 }
211 
220 char *osync_print_binary(const unsigned char *data, int len)
221 {
222  int t;
223  GString *str = g_string_new("");
224  for (t = 0; t < len; t++) {
225  if (data[t] >= ' ' && data[t] <= 'z')
226  g_string_append_c(str, data[t]);
227  else
228  g_string_append_printf(str, " %02x ", data[t]);
229  }
230  return g_string_free(str, FALSE);
231 }
232 
241 char *osync_rand_str(int maxlength)
242 {
243  char *randchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ1234567890";
244 
245  int length;
246  char *retchar;
247  int i = 0;
248 
249  length = g_random_int_range(1, maxlength + 1);
250  retchar = malloc(length * sizeof(char) + 1);
251  retchar[0] = 0;
252 
253  for (i = 0; i < length; i++) {
254  retchar[i] = randchars[g_random_int_range(0, strlen(randchars))];
255  retchar[i + 1] = 0;
256  }
257 
258  return retchar;
259 }
260 
char * osync_print_binary(const unsigned char *data, int len)
Used for printing binary data.
void osync_debug(const char *subpart, int level, const char *message,...)
Used for debugging.
char * osync_rand_str(int maxlength)
Creates a random string.
void osync_trace_reset_indent(void)
void osync_trace(OSyncTraceType type, const char *message,...)
Used for tracing the application.
OSyncTraceType
The type of the trace.
Definition: opensync_debug.h:6