Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Quesnel <131881+aquesnel@users.noreply.github.com>2021-02-28 22:50:16 +0300
committerAlexandre Quesnel <131881+aquesnel@users.noreply.github.com>2021-03-26 16:58:27 +0300
commitb8d02823d1d02a4231cff7cf747dd4bd0c76428b (patch)
tree42116bce65d7f0c55e7c233dcf4809fa0210f8cd
parentec52c6466d70a56fec2a454f6c60130f05a6cf2f (diff)
Extracting bytes_to_hexdump function from logging implementation
-rw-r--r--common/log.c150
-rw-r--r--common/log.h21
-rw-r--r--common/string_calls.c126
-rw-r--r--common/string_calls.h23
4 files changed, 201 insertions, 119 deletions
diff --git a/common/log.c b/common/log.c
index 0c5465d3..ad076090 100644
--- a/common/log.c
+++ b/common/log.c
@@ -764,7 +764,18 @@ log_end(void)
}
/*****************************************************************************/
-/* produce a hex dump */
+/* log a hex dump */
+enum logReturns
+log_hexdump(const enum logLevels log_level,
+ const char *message,
+ const char *src,
+ int len)
+{
+ return log_hexdump_with_location("", "", 0, log_level, message, src, len);
+}
+
+/*****************************************************************************/
+/* log a hex dump */
enum logReturns
log_hexdump_with_location(const char *function_name,
const char *file_name,
@@ -774,38 +785,11 @@ log_hexdump_with_location(const char *function_name,
const char *src,
int len)
{
- unsigned char *line;
- int i;
- int dump_number_lines;
- int dump_line_length;
- int dump_length;
- int dump_offset;
- int thisline;
- int offset;
char *dump_buffer;
- enum logReturns rv;
+ enum logReturns rv = LOG_STARTUP_OK;
enum logLevels override_log_level;
bool_t override_destination_level = 0;
- /* Start the dump on a new line so that the first line of the dump is
- aligned to the first column instead of to after the log message
- preamble (eg. time, log level, ...)
- */
-#define HEX_DUMP_SOURCE_BYTES_PER_LINE (16)
-#ifdef _WIN32
-#define HEX_DUMP_HEADER ("%s Hex Dump:\r\n")
-#define HEX_DUMP_NEWLINE_SIZE (2)
-#else
-#ifdef _MACOS
-#define HEX_DUMP_HEADER ("%s Hex Dump:\r")
-#define HEX_DUMP_NEWLINE_SIZE (1)
-#else
-#define HEX_DUMP_HEADER ("%s Hex Dump:\n")
-#define HEX_DUMP_NEWLINE_SIZE (1)
-#endif
-#endif
-#define HEX_DUMP_HEADER_SIZE (sizeof(HEX_DUMP_HEADER) - 1)
-
override_destination_level = internal_log_location_overrides_level(
function_name,
file_name,
@@ -815,107 +799,37 @@ log_hexdump_with_location(const char *function_name,
return LOG_STARTUP_OK;
}
- dump_line_length = (4 + 3 /* = 4 offset + 3 space */
- + ((2 + 1) * HEX_DUMP_SOURCE_BYTES_PER_LINE) /* + (2 hex char + 1 space) per source byte */
- + 2 /* + 2 space */
- + HEX_DUMP_SOURCE_BYTES_PER_LINE
- + HEX_DUMP_NEWLINE_SIZE);
-
- dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */
- dump_length = (dump_number_lines *dump_line_length /* hex dump lines */
- + HEX_DUMP_HEADER_SIZE
- + 1); /* terminating NULL */
- dump_buffer = (char *)g_malloc(dump_length, 1);
- if (dump_buffer == NULL)
- {
- LOG_DEVEL(LOG_LEVEL_WARNING,
- "Failed to allocate buffer for hex dump of size %d",
- dump_length);
- return LOG_ERROR_MALLOC;
- }
-
- line = (unsigned char *)src;
- offset = 0;
-
- g_memcpy(dump_buffer, HEX_DUMP_HEADER, HEX_DUMP_HEADER_SIZE);
- dump_offset = HEX_DUMP_HEADER_SIZE;
-
- while (offset < len)
- {
- g_sprintf(dump_buffer + dump_offset, "%04x ", offset);
- dump_offset += 7;
- thisline = len - offset;
-
- if (thisline > HEX_DUMP_SOURCE_BYTES_PER_LINE)
- {
- thisline = HEX_DUMP_SOURCE_BYTES_PER_LINE;
- }
-
- for (i = 0; i < thisline; i++)
- {
- g_sprintf(dump_buffer + dump_offset, "%02x ", line[i]);
- dump_offset += 3;
- }
-
- for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
- {
- dump_buffer[dump_offset++] = ' ';
- dump_buffer[dump_offset++] = ' ';
- dump_buffer[dump_offset++] = ' ';
- }
-
- dump_buffer[dump_offset++] = ' ';
- dump_buffer[dump_offset++] = ' ';
-
- for (i = 0; i < thisline; i++)
- {
- dump_buffer[dump_offset++] = (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.';
- }
-
- for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
- {
- dump_buffer[dump_offset++] = ' ';
- }
-
+ /* Start the dump on a new line so that the first line of the dump is
+ aligned to the first column instead of to after the log message
+ preamble (eg. time, log level, ...)
+ */
#ifdef _WIN32
- dump_buffer[dump_offset++] = '\r';
- dump_buffer[dump_offset++] = '\n';
+#define HEX_DUMP_HEADER ("Hex Dump:\r\n")
#else
#ifdef _MACOS
- dump_buffer[dump_offset++] = '\r';
+#define HEX_DUMP_HEADER ("Hex Dump:\r")
#else
- dump_buffer[dump_offset++] = '\n';
+#define HEX_DUMP_HEADER ("Hex Dump:\n")
#endif
#endif
- offset += thisline;
- line += thisline;
+ dump_buffer = g_bytes_to_hexdump(src, len);
- if ((dump_offset - HEX_DUMP_HEADER_SIZE) % dump_line_length != 0)
+ if (dump_buffer != NULL)
+ {
+ if (g_strlen(file_name) > 0)
{
- LOG_DEVEL(LOG_LEVEL_ERROR,
- "BUG: dump_offset (%d) at the end of a line is not a "
- "multiple of the line length (%d)",
- dump_offset, dump_line_length);
+ rv = log_message_with_location(function_name, file_name, line_number,
+ log_level, "%s %s%s",
+ message, HEX_DUMP_HEADER, dump_buffer);
+ }
+ else
+ {
+ rv = log_message(log_level, "%s %s%s",
+ message, HEX_DUMP_HEADER, dump_buffer);
}
-
- }
- if (dump_offset > dump_length)
- {
- LOG_DEVEL(LOG_LEVEL_ERROR,
- "BUG: dump_offset (%d) is larger than the dump_buffer length (%d)",
- dump_offset, dump_length);
g_free(dump_buffer);
- return LOG_GENERAL_ERROR;
}
-
- /* replace the last new line with the end of the string since log_message
- will add a new line */
- dump_buffer[dump_offset - HEX_DUMP_NEWLINE_SIZE] = '\0';
-
- rv = log_message_with_location(function_name, file_name, line_number,
- log_level, dump_buffer, message);
- g_free(dump_buffer);
return rv;
}
diff --git a/common/log.h b/common/log.h
index bc86c1e5..97f17d86 100644
--- a/common/log.h
+++ b/common/log.h
@@ -127,8 +127,23 @@ enum logReturns
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length)
+/**
+ * @brief Logging macro for logging the contents of a byte array using a hex
+ * dump format.
+ *
+ * @param log_level, the log level
+ * @param message, a message prefix for the hex dump. Note: no printf like
+ * formatting is done to this message.
+ * @param buffer, a pointer to the byte array to log as a hex dump
+ * @param length, the length of the byte array to log
+ */
+#define LOG_HEXDUMP(log_level, message, buffer, length) \
+ log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length)
+
#else
#define LOG(log_level, args...) log_message(log_level, args)
+#define LOG_HEXDUMP(log_level, message, buffer, length) \
+ log_hexdump(log_level, message, buffer, length)
/* Since log_message() returns a value ensure that the elided versions of
* LOG_DEVEL and LOG_DEVEL_HEXDUMP also "fake" returning the success value
@@ -345,6 +360,12 @@ log_end(void);
enum logReturns
log_message(const enum logLevels lvl, const char *msg, ...) printflike(2, 3);
+enum logReturns
+log_hexdump(const enum logLevels log_level,
+ const char *msg,
+ const char *p,
+ int len);
+
/**
* the log function that all files use to log an event,
* with the function name and file line.
diff --git a/common/string_calls.c b/common/string_calls.c
index 6023347b..18b6acf4 100644
--- a/common/string_calls.c
+++ b/common/string_calls.c
@@ -25,8 +25,9 @@
#include <strings.h>
#include <stdlib.h>
-#include "string_calls.h"
+#include "log.h"
#include "os_calls.h"
+#include "string_calls.h"
unsigned int
g_format_info_string(char *dest, unsigned int len,
@@ -471,6 +472,129 @@ g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
}
/*****************************************************************************/
+/* convert a byte array into a hex dump */
+char *
+g_bytes_to_hexdump(const char *src, int len)
+{
+ unsigned char *line;
+ int i;
+ int dump_number_lines;
+ int dump_line_length;
+ int dump_length;
+ int dump_offset;
+ int thisline;
+ int offset;
+ char *dump_buffer;
+
+#define HEX_DUMP_SOURCE_BYTES_PER_LINE (16)
+#ifdef _WIN32
+#define HEX_DUMP_NEWLINE_SIZE (2)
+#else
+#ifdef _MACOS
+#define HEX_DUMP_NEWLINE_SIZE (1)
+#else
+#define HEX_DUMP_NEWLINE_SIZE (1)
+#endif
+#endif
+
+ dump_line_length = (4 + 3 /* = 4 offset + 3 space */
+ + ((2 + 1) * HEX_DUMP_SOURCE_BYTES_PER_LINE) /* + (2 hex char + 1 space) per source byte */
+ + 2 /* + 2 space */
+ + HEX_DUMP_SOURCE_BYTES_PER_LINE
+ + HEX_DUMP_NEWLINE_SIZE);
+
+ dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */
+ dump_length = (dump_number_lines *dump_line_length /* hex dump lines */
+ + 1); /* terminating NULL */
+ dump_buffer = (char *)g_malloc(dump_length, 1);
+ if (dump_buffer == NULL)
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "Failed to allocate buffer for hex dump of size %d",
+ dump_length);
+ return NULL;
+ }
+
+ line = (unsigned char *)src;
+ offset = 0;
+ dump_offset = 0;
+
+ while (offset < len)
+ {
+ g_sprintf(dump_buffer + dump_offset, "%04x ", offset);
+ dump_offset += 7;
+ thisline = len - offset;
+
+ if (thisline > HEX_DUMP_SOURCE_BYTES_PER_LINE)
+ {
+ thisline = HEX_DUMP_SOURCE_BYTES_PER_LINE;
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ g_sprintf(dump_buffer + dump_offset, "%02x ", line[i]);
+ dump_offset += 3;
+ }
+
+ for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
+ {
+ dump_buffer[dump_offset++] = ' ';
+ dump_buffer[dump_offset++] = ' ';
+ dump_buffer[dump_offset++] = ' ';
+ }
+
+ dump_buffer[dump_offset++] = ' ';
+ dump_buffer[dump_offset++] = ' ';
+
+ for (i = 0; i < thisline; i++)
+ {
+ dump_buffer[dump_offset++] = (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.';
+ }
+
+ for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
+ {
+ dump_buffer[dump_offset++] = ' ';
+ }
+
+#ifdef _WIN32
+ dump_buffer[dump_offset++] = '\r';
+ dump_buffer[dump_offset++] = '\n';
+#else
+#ifdef _MACOS
+ dump_buffer[dump_offset++] = '\r';
+#else
+ dump_buffer[dump_offset++] = '\n';
+#endif
+#endif
+ offset += thisline;
+ line += thisline;
+
+
+ if (dump_offset % dump_line_length != 0)
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "BUG: dump_offset (%d) at the end of a line is not a "
+ "multiple of the line length (%d)",
+ dump_offset, dump_line_length);
+ }
+
+ }
+ if (dump_offset > dump_length)
+ {
+ LOG_DEVEL(LOG_LEVEL_WARNING,
+ "BUG: dump_offset (%d) is larger than the dump_buffer length (%d)",
+ dump_offset, dump_length);
+ dump_buffer[0] = '\0';
+ return dump_buffer;
+ }
+
+ /* replace the last new line with the end of the string since log_message
+ will add a new line */
+ dump_buffer[dump_offset - HEX_DUMP_NEWLINE_SIZE] = '\0';
+ return dump_buffer;
+}
+
+/*****************************************************************************/
int
g_pos(const char *str, const char *to_find)
{
diff --git a/common/string_calls.h b/common/string_calls.h
index cce332ac..4b20a595 100644
--- a/common/string_calls.h
+++ b/common/string_calls.h
@@ -80,6 +80,29 @@ g_bool2text(int value);
int
g_text2bool(const char *s);
+/**
+ * Converts a binary array into a hux dump suitable for displaying to a user.
+ *
+ * The format of the hex dump is:
+ * 0000 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 ................
+ * /\ /\ /\
+ * | | |
+ * | | ascii representation of bytes
+ * | hex representation of bytes
+ * offset from beining of the byte array in hex
+ *
+ * Note: the ascii representation uses '.' for all non-printable
+ * characters (eg. below 32 or above 127).
+ *
+ * Note: the string contains embedded new lines, but is not new line terminated.
+ *
+ * @param[in] src Value to convert
+ * @param[in] len The number of bytes in src to convert
+ * @return string containing the hex dump that must be free'd by the caller
+ */
+char *
+g_bytes_to_hexdump(const char *src, int len);
+
int g_strlen(const char *text);
const char *g_strchr(const char *text, int c);
char *g_strcpy(char *dest, const char *src);