LIBSSDP
 All Classes Files Functions Variables Typedefs Macros
log.c
Go to the documentation of this file.
1 
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 
15 #include "log.h"
16 
18 #define MESSAGE_MAX_SIZE 20480
19 
20 #ifdef DEBUG___
21 
29 static int chr_count(char *haystack, char needle) {
30  int count = 0;
31  int len = strlen(haystack);
32  int i;
33  for (i = 0; i < len; i++) {
34  if (haystack[i] == needle) {
35  count++;
36  }
37  }
38  return count;
39 }
40 
41 #ifdef DEBUG_TO_FILE___
42 
49 static int fsize(const char *file) {
50  struct stat st;
51 
52  if(stat(file, &st) == 0) {
53  return st.st_size;
54  }
55 
56  return -1;
57 }
58 #endif
59 
60 void print_debug(FILE *std, const char *color, const char* file, int line,
61  char *va_format, ...) {
62  va_list va;
63  char message[MESSAGE_MAX_SIZE];
64  int message_used = 0;
65  char *from_pointer = va_format;
66  char header[100];
67  char *to_pointer = va_format;
68  int args_count = chr_count(va_format, '%');
69  const char *no_memory =
70  "Not enought memory in buffer to build debug message";
71  char *s;
72  char c;
73  int d;
74 
75  /* Remove path from file variable (borrowing 'c' for the task) */
76  s = strrchr(file, '/');
77  if (s) {
78  file = s + 1;
79  s = NULL;
80  }
81 
82  /* Create a nice header for the output */
83  sprintf(header, "%s[%d][%s:%04d] ", color, (int)getpid(), file, line);
84 
85  if(!va_format) {
86  fprintf(stderr, "%s[%d][%s:%d] Error, va_arg input format (va_format) "
87  "not set%s\n", ANSI_COLOR_RED, (int)getpid(), __FILE__, __LINE__,
89  printf("some rror\n");
90  return;
91  }
92 
93  int message_length = 20480;
94  memset(message, '\0', sizeof(char) * message_length);
95  message_length -= 50; // compensate for additional chars in the message
96  va_start(va, va_format);
97 
98  int copy_length = 0;
99  int args_pos;
100 
101  for (args_pos = 1; (from_pointer && *from_pointer != '\0');
102  from_pointer = to_pointer) {
103 
104  to_pointer = strchr(from_pointer, '%');
105 
106  if (to_pointer && strlen(to_pointer) > 1) {
107  copy_length = to_pointer - from_pointer;
108 
109  if (copy_length > message_length - message_used) {
110  fprintf(stderr, "%s[%d][%s:%d] %s%s\n", ANSI_COLOR_RED, (int)getpid(),
111  __FILE__, __LINE__, no_memory, ANSI_COLOR_RESET);
112  return;
113  }
114 
115  strncpy(message + message_used, from_pointer, copy_length);
116  message_used += copy_length;
117 
118  switch(to_pointer[1]) {
119  case 's':
120  /* string */
121  s = va_arg(va, char *);
122  if(s) {
123  copy_length = strlen(s);
124  if (copy_length > message_length - message_used) {
125  fprintf(stderr, "%s[%d][%s:%d] %s%s\n", ANSI_COLOR_RED,
126  (int)getpid(), __FILE__, __LINE__, no_memory, ANSI_COLOR_RESET);
127  return;
128  }
129  strncpy(message + message_used, s, copy_length);
130  message_used += copy_length;
131  }
132  else {
133  copy_length = 6;
134  strncpy(message + message_used, "NULL", copy_length);
135  message_used += copy_length;
136  }
137  break;
138  case 'c':
139  /* character */
140  c = (char)va_arg(va, int);
141  copy_length = 1;
142  if (copy_length > message_length - message_used) {
143  fprintf(stderr, "%s[%d][%s:%d] %s%s\n", ANSI_COLOR_RED, (int)getpid(),
144  __FILE__, __LINE__, no_memory, ANSI_COLOR_RESET);
145  return;
146  }
147  strncpy(message + message_used, &c, copy_length);
148  message_used += copy_length;
149  break;
150  case 'd':
151  /* integer */
152  d = va_arg(va, int);
153  char *d_char = (char *)malloc(sizeof(char) * 10);
154  memset(d_char, '\0', 10);
155  sprintf(d_char, "%d", d);
156  copy_length = strlen(d_char);
157  if (copy_length > message_length - message_used) {
158  fprintf(stderr, "%s[%d][%s:%d] %s%s\n", ANSI_COLOR_RED, (int)getpid(),
159  __FILE__, __LINE__, no_memory, ANSI_COLOR_RESET);
160  free(d_char);
161  return;
162  }
163  strncpy(message + message_used, d_char, copy_length);
164  message_used += copy_length;
165  free(d_char);
166  break;
167  default:
168  break;
169  }
170 
171  to_pointer += 2;
172  }
173  else {
174  strcat(message, from_pointer);
175  to_pointer = NULL;
176  }
177 
178  if(args_pos > args_count) {
179  break;
180  }
181  args_pos++;
182  }
183 
184  if (!std) {
185  std = stdout;
186  }
187 
188  #ifdef DEBUG_TO_FILE___
189  /* Debug file to write to */
190  const char debug_file[] = "debug.log";
191  FILE *fh = NULL;
192  int file_size = fsize(debug_file);
193  /* Max file size is 500 KB */
194  int max_size = 512000;
195  /* If file is larger than 500KB then trunkate it */
196  if (file_size > max_size) {
197  fh = fopen(debug_file, "w");
198  }
199  /* Else continue writing to it */
200  else {
201  fh = fopen(debug_file, "a");
202  }
203 
204  if (NULL == fh) {
205  fprintf(stderr, "%s[%d][%s:%d] Failed to create debug file%s\n",
206  ANSI_COLOR_RED, (int)getpid(), __FILE__, __LINE__, ANSI_COLOR_RESET);
207  }
208  else {
209  fprintf(fh, "%s%s%s\n", header, message, ANSI_COLOR_RESET);
210  fclose(fh);
211  }
212  #else
213  fprintf(std, "%s%s%s\n", header, message, ANSI_COLOR_RESET);
214  #endif
215 
216 }
217 #endif
218 
219 void log_start_args(int argc, char **argv) {
220  char *cmdline;
221  int cmdline_len = 0;
222  int i;
223 
224  for (i = 0; i < argc; ++i) {
225  cmdline_len += strlen(argv[i]) + 1;
226  }
227 
228  cmdline = malloc(cmdline_len + 1);
229  cmdline[0] = '\0';
230 
231  for (i = 0; i < argc; ++i) {
232  strcat(cmdline, argv[i]);
233  strcat (cmdline, " ");
234  }
235 
236  PRINT_DEBUG("%s", cmdline);
237 
238  free(cmdline);
239 }
static int fsize(const char *file)
Definition: log.c:49
void print_debug(FILE *std, const char *color, const char *file, int line, char *va_format,...)
Definition: log.c:60
#define MESSAGE_MAX_SIZE
Definition: log.c:18
void log_start_args(int argc, char **argv)
Definition: log.c:219
#define ANSI_COLOR_RED
Definition: log.h:30
#define ANSI_COLOR_RESET
Definition: log.h:32
static int chr_count(char *haystack, char needle)
Definition: log.c:29