| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
- #include "private-lib-core.h"
- #ifdef LWS_HAVE_SYS_TYPES_H
- #include <sys/types.h>
- #endif
- #if defined(LWS_PLAT_OPTEE)
- void lwsl_emit_optee(int level, const char *line);
- #endif
- int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
- static void (*lwsl_emit)(int level, const char *line)
- #ifndef LWS_PLAT_OPTEE
- = lwsl_emit_stderr
- #else
- = lwsl_emit_optee;
- #endif
- ;
- #ifndef LWS_PLAT_OPTEE
- static const char * log_level_names ="EWNIDPHXCLUT??";
- #endif
- #if defined(LWS_LOGS_TIMESTAMP)
- int
- lwsl_timestamp(int level, char *p, int len)
- {
- #ifndef LWS_PLAT_OPTEE
- time_t o_now;
- unsigned long long now;
- struct timeval tv;
- struct tm *ptm = NULL;
- #ifndef WIN32
- struct tm tm;
- #endif
- int n;
- gettimeofday(&tv, NULL);
- o_now = tv.tv_sec;
- now = ((unsigned long long)tv.tv_sec * 10000) + (tv.tv_usec / 100);
- #ifndef _WIN32_WCE
- #ifdef WIN32
- ptm = localtime(&o_now);
- #else
- if (localtime_r(&o_now, &tm))
- ptm = &tm;
- #endif
- #endif
- p[0] = '\0';
- for (n = 0; n < LLL_COUNT; n++) {
- if (level != (1 << n))
- continue;
- if (ptm)
- n = lws_snprintf(p, len,
- "[%04d/%02d/%02d %02d:%02d:%02d:%04d] %c: ",
- ptm->tm_year + 1900,
- ptm->tm_mon + 1,
- ptm->tm_mday,
- ptm->tm_hour,
- ptm->tm_min,
- ptm->tm_sec,
- (int)(now % 10000), log_level_names[n]);
- else
- n = lws_snprintf(p, len, "[%llu:%04d] %c: ",
- (unsigned long long) now / 10000,
- (int)(now % 10000), log_level_names[n]);
- return n;
- }
- #else
- p[0] = '\0';
- #endif
- return 0;
- }
- #endif
- #ifndef LWS_PLAT_OPTEE
- static const char * const colours[] = {
- "[31;1m", /* LLL_ERR */
- "[36;1m", /* LLL_WARN */
- "[35;1m", /* LLL_NOTICE */
- "[32;1m", /* LLL_INFO */
- "[34;1m", /* LLL_DEBUG */
- "[33;1m", /* LLL_PARSER */
- "[33m", /* LLL_HEADER */
- "[33m", /* LLL_EXT */
- "[33m", /* LLL_CLIENT */
- "[33;1m", /* LLL_LATENCY */
- "[0;1m", /* LLL_USER */
- "[31m", /* LLL_THREAD */
- };
- static char tty;
- static void
- _lwsl_emit_stderr(int level, const char *line, int ts)
- {
- char buf[50];
- int n, m = LWS_ARRAY_SIZE(colours) - 1;
- if (!tty)
- tty = isatty(2) | 2;
- buf[0] = '\0';
- #if defined(LWS_LOGS_TIMESTAMP)
- if (ts)
- lwsl_timestamp(level, buf, sizeof(buf));
- #endif
- if (tty == 3) {
- n = 1 << (LWS_ARRAY_SIZE(colours) - 1);
- while (n) {
- if (level & n)
- break;
- m--;
- n >>= 1;
- }
- fprintf(stderr, "%c%s%s%s%c[0m", 27, colours[m], buf, line, 27);
- } else
- fprintf(stderr, "%s%s", buf, line);
- }
- void
- lwsl_emit_stderr(int level, const char *line)
- {
- _lwsl_emit_stderr(level, line, 1);
- }
- void
- lwsl_emit_stderr_notimestamp(int level, const char *line)
- {
- _lwsl_emit_stderr(level, line, 0);
- }
- #endif
- #if !(defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_NETWORK))
- void _lws_logv(int filter, const char *format, va_list vl)
- {
- #if LWS_MAX_SMP == 1 && !defined(LWS_WITH_THREADPOOL)
- /* this is incompatible with multithreaded logging */
- static char buf[256];
- #else
- char buf[1024];
- #endif
- int n;
- if (!(log_level & filter))
- return;
- n = vsnprintf(buf, sizeof(buf) - 1, format, vl);
- (void)n;
- /* vnsprintf returns what it would have written, even if truncated */
- if (n > (int)sizeof(buf) - 1) {
- n = sizeof(buf) - 5;
- buf[n++] = '.';
- buf[n++] = '.';
- buf[n++] = '.';
- buf[n++] = '\n';
- buf[n] = '\0';
- }
- if (n > 0)
- buf[n] = '\0';
- lwsl_emit(filter, buf);
- }
- void _lws_log(int filter, const char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- _lws_logv(filter, format, ap);
- va_end(ap);
- }
- #endif
- void lws_set_log_level(int level, void (*func)(int level, const char *line))
- {
- log_level = level;
- if (func)
- lwsl_emit = func;
- }
- int lwsl_visible(int level)
- {
- return log_level & level;
- }
- void
- lwsl_hexdump_level(int hexdump_level, const void *vbuf, size_t len)
- {
- unsigned char *buf = (unsigned char *)vbuf;
- unsigned int n;
- if (!lwsl_visible(hexdump_level))
- return;
- if (!len) {
- _lws_log(hexdump_level, "(hexdump: zero length)\n");
- return;
- }
- if (!vbuf) {
- _lws_log(hexdump_level, "(hexdump: NULL ptr)\n");
- return;
- }
- _lws_log(hexdump_level, "\n");
- for (n = 0; n < len;) {
- unsigned int start = n, m;
- char line[80], *p = line;
- p += lws_snprintf(p, 10, "%04X: ", start);
- for (m = 0; m < 16 && n < len; m++)
- p += lws_snprintf(p, 5, "%02X ", buf[n++]);
- while (m++ < 16)
- p += lws_snprintf(p, 5, " ");
- p += lws_snprintf(p, 6, " ");
- for (m = 0; m < 16 && (start + m) < len; m++) {
- if (buf[start + m] >= ' ' && buf[start + m] < 127)
- *p++ = buf[start + m];
- else
- *p++ = '.';
- }
- while (m++ < 16)
- *p++ = ' ';
- *p++ = '\n';
- *p = '\0';
- _lws_log(hexdump_level, "%s", line);
- (void)line;
- }
- _lws_log(hexdump_level, "\n");
- }
- void
- lwsl_hexdump(const void *vbuf, size_t len)
- {
- #if defined(_DEBUG)
- lwsl_hexdump_level(LLL_DEBUG, vbuf, len);
- #endif
- }
|