/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Common operations for "remote" processes for the Mirror VFD. * * Jacob Smith, 2020-03-06 */ #include "mirror_remote.h" #ifdef H5_HAVE_MIRROR_VFD /* --------------------------------------------------------------------------- * Function: mirror_log * * Purpose: Write message to the logging stream/file. * If logging info pointer is NULL, uses logging defaults. * ---------------------------------------------------------------------------- */ void mirror_log(struct mirror_log_info *info, unsigned int level, const char *format, ...) { FILE * stream = MIRROR_LOG_DEFAULT_STREAM; unsigned int verbosity = MIRROR_LOG_DEFAULT_VERBOSITY; hbool_t custom = FALSE; if (info != NULL && info->magic == MIRROR_LOG_INFO_MAGIC) { stream = info->stream; verbosity = info->verbosity; custom = TRUE; } if (level == V_NONE) { return; } else if (level <= verbosity) { if (custom == TRUE && info->prefix[0] != '\0') { HDfprintf(stream, "%s", info->prefix); } switch (level) { case (V_ERR): HDfprintf(stream, "ERROR "); break; case (V_WARN): HDfprintf(stream, "WARNING "); break; default: break; } if (format != NULL) { va_list args; HDva_start(args, format); HDvfprintf(stream, format, args); HDva_end(args); } HDfprintf(stream, "\n"); HDfflush(stream); } /* end if sufficiently verbose to print */ } /* end mirror_log() */ /* --------------------------------------------------------------------------- * Function: session_log_bytes * * Purpose: "Pretty-print" raw binary data to logging stream/file. * If info pointer is NULL, uses logging defaults. * ---------------------------------------------------------------------------- */ void mirror_log_bytes(struct mirror_log_info *info, unsigned int level, size_t n_bytes, const unsigned char *buf) { FILE * stream = MIRROR_LOG_DEFAULT_STREAM; unsigned int verbosity = MIRROR_LOG_DEFAULT_VERBOSITY; if (buf == NULL) { return; } if (info != NULL && info->magic == MIRROR_LOG_INFO_MAGIC) { stream = info->stream; verbosity = info->verbosity; } if (level <= verbosity) { size_t bytes_written = 0; const unsigned char *b = NULL; /* print whole lines */ while ((n_bytes - bytes_written) >= 32) { b = buf + bytes_written; /* point to region in buffer */ HDfprintf(stream, "%04zX %02X%02X%02X%02X %02X%02X%02X%02X" " %02X%02X%02X%02X %02X%02X%02X%02X" " %02X%02X%02X%02X %02X%02X%02X%02X" " %02X%02X%02X%02X %02X%02X%02X%02X\n", bytes_written, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], b[30], b[31]); bytes_written += 32; } /* start partial line */ if (n_bytes > bytes_written) { HDfprintf(stream, "%04zX ", bytes_written); } /* partial line blocks */ while ((n_bytes - bytes_written) >= 4) { HDfprintf(stream, " %02X%02X%02X%02X", buf[bytes_written], buf[bytes_written + 1], buf[bytes_written + 2], buf[bytes_written + 3]); bytes_written += 4; } /* block separator before partial block */ if (n_bytes > bytes_written) { HDfprintf(stream, " "); } /* partial block individual bytes */ while (n_bytes > bytes_written) { HDfprintf(stream, "%02X", buf[bytes_written++]); } /* end partial line */ HDfprintf(stream, "\n"); } /* end if suitably verbose to log */ } /* end mirror_log_bytes() */ /* --------------------------------------------------------------------------- * Function: mirror_log_init * * Purpose: Prepare a loginfo_t structure for use. * * Return: Success: Pointer to newly-ceated info. * Failure: NULL. Either unable to allocate or cannot open file. * ---------------------------------------------------------------------------- */ loginfo_t * mirror_log_init(char *path, const char *prefix, unsigned int verbosity) { loginfo_t *info = NULL; info = (loginfo_t *)HDmalloc(sizeof(loginfo_t)); if (info != NULL) { info->magic = MIRROR_LOG_INFO_MAGIC; info->verbosity = verbosity; info->stream = MIRROR_LOG_DEFAULT_STREAM; info->prefix[0] = '\0'; if (prefix && *prefix) { HDstrncpy(info->prefix, prefix, MIRROR_LOG_PREFIX_MAX); } if (path && *path) { FILE *f = NULL; f = HDfopen(path, "w"); if (NULL == f) { HDfprintf(MIRROR_LOG_DEFAULT_STREAM, "WARN custom logging path could not be opened: %s\n", path); info->magic += 1; HDfree(info); } else { info->stream = f; } } } /* end if able to allocate */ return info; } /* end mirror_log_init() */ /* --------------------------------------------------------------------------- * Function: mirror_log_term * * Purpose: Shut down and clean up a loginfo_t structure. * * Return: Success: SUCCEED. Resources released. * Failure: FAIL. Indeterminite state. * ---------------------------------------------------------------------------- */ herr_t mirror_log_term(loginfo_t *info) { if (info == NULL || info->magic != MIRROR_LOG_INFO_MAGIC) { return FAIL; } if (info->stream != stderr || info->stream != stdout) { if (HDfclose(info->stream) < 0) { return FAIL; } } info->magic += 1; HDfree(info); return SUCCEED; } /* end mirror_log_term() */ #endif /* H5_HAVE_MIRROR_VFD */