More for input buffer checks
[rtmpdump.git] / librtmp / log.c
blob1b52000071dca9d45d271d426a2fa615bb7f3468
1 /*
2 * Copyright (C) 2008-2009 Andrej Stepanchuk
3 * Copyright (C) 2009-2010 Howard Chu
5 * This file is part of librtmp.
7 * librtmp is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1,
10 * or (at your option) any later version.
12 * librtmp is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with librtmp see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/lgpl.html
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <ctype.h>
30 #include "rtmp_sys.h"
31 #include "log.h"
33 #define MAX_PRINT_LEN 2048
35 RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
37 static int neednl;
39 static FILE *fmsg;
41 static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
43 static const char *levels[] = {
44 "CRIT", "ERROR", "WARNING", "INFO",
45 "DEBUG", "DEBUG2"
48 static void rtmp_log_default(int level, const char *format, va_list vl)
50 char str[MAX_PRINT_LEN]="";
52 vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
54 /* Filter out 'no-name' */
55 if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
56 return;
58 if ( !fmsg ) fmsg = stderr;
60 if ( level <= RTMP_debuglevel ) {
61 if (neednl) {
62 putc('\n', fmsg);
63 neednl = 0;
65 fprintf(fmsg, "%s: %s\n", levels[level], str);
66 #ifdef _DEBUG
67 fflush(fmsg);
68 #endif
72 void RTMP_LogSetOutput(FILE *file)
74 fmsg = file;
77 void RTMP_LogSetLevel(RTMP_LogLevel level)
79 RTMP_debuglevel = level;
82 void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
84 cb = cbp;
87 RTMP_LogLevel RTMP_LogGetLevel()
89 return RTMP_debuglevel;
92 void RTMP_Log(int level, const char *format, ...)
94 va_list args;
96 if ( level > RTMP_debuglevel )
97 return;
99 va_start(args, format);
100 cb(level, format, args);
101 va_end(args);
104 static const char hexdig[] = "0123456789abcdef";
106 void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
108 unsigned long i;
109 char line[50], *ptr;
111 if ( level > RTMP_debuglevel )
112 return;
114 ptr = line;
116 for(i=0; i<len; i++) {
117 *ptr++ = hexdig[0x0f & (data[i] >> 4)];
118 *ptr++ = hexdig[0x0f & data[i]];
119 if ((i & 0x0f) == 0x0f) {
120 *ptr = '\0';
121 ptr = line;
122 RTMP_Log(level, "%s", line);
123 } else {
124 *ptr++ = ' ';
127 if (i & 0x0f) {
128 *ptr = '\0';
129 RTMP_Log(level, "%s", line);
133 void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
135 #define BP_OFFSET 9
136 #define BP_GRAPH 60
137 #define BP_LEN 80
138 char line[BP_LEN];
139 unsigned long i;
141 if ( !data || level > RTMP_debuglevel )
142 return;
144 /* in case len is zero */
145 line[0] = '\0';
147 for ( i = 0 ; i < len ; i++ ) {
148 int n = i % 16;
149 unsigned off;
151 if( !n ) {
152 if( i ) RTMP_Log( level, "%s", line );
153 memset( line, ' ', sizeof(line)-2 );
154 line[sizeof(line)-2] = '\0';
156 off = i % 0x0ffffU;
158 line[2] = hexdig[0x0f & (off >> 12)];
159 line[3] = hexdig[0x0f & (off >> 8)];
160 line[4] = hexdig[0x0f & (off >> 4)];
161 line[5] = hexdig[0x0f & off];
162 line[6] = ':';
165 off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
166 line[off] = hexdig[0x0f & ( data[i] >> 4 )];
167 line[off+1] = hexdig[0x0f & data[i]];
169 off = BP_GRAPH + n + ((n >= 8)?1:0);
171 if ( isprint( data[i] )) {
172 line[BP_GRAPH + n] = data[i];
173 } else {
174 line[BP_GRAPH + n] = '.';
178 RTMP_Log( level, "%s", line );
181 /* These should only be used by apps, never by the library itself */
182 void RTMP_LogPrintf(const char *format, ...)
184 char str[MAX_PRINT_LEN]="";
185 int len;
186 va_list args;
187 va_start(args, format);
188 len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
189 va_end(args);
191 if ( RTMP_debuglevel==RTMP_LOGCRIT )
192 return;
194 if ( !fmsg ) fmsg = stderr;
196 if (neednl) {
197 putc('\n', fmsg);
198 neednl = 0;
201 if (len > MAX_PRINT_LEN-1)
202 len = MAX_PRINT_LEN-1;
203 fprintf(fmsg, "%s", str);
204 if (str[len-1] == '\n')
205 fflush(fmsg);
208 void RTMP_LogStatus(const char *format, ...)
210 char str[MAX_PRINT_LEN]="";
211 va_list args;
212 va_start(args, format);
213 vsnprintf(str, MAX_PRINT_LEN-1, format, args);
214 va_end(args);
216 if ( RTMP_debuglevel==RTMP_LOGCRIT )
217 return;
219 if ( !fmsg ) fmsg = stderr;
221 fprintf(fmsg, "%s", str);
222 fflush(fmsg);
223 neednl = 1;