1 /*
2  * Copyright 2019-present MongoDB, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "mongocrypt-config.h"
18 #include "mongocrypt-log-private.h"
19 #include "mongocrypt-opts-private.h"
20 
21 #include <bson/bson.h>
22 
23 void
_mongocrypt_log_init(_mongocrypt_log_t * log)24 _mongocrypt_log_init (_mongocrypt_log_t *log)
25 {
26    _mongocrypt_mutex_init (&log->mutex);
27    /* Initially, no log function is set. */
28    _mongocrypt_log_set_fn (log, NULL, NULL);
29 #ifdef MONGOCRYPT_ENABLE_TRACE
30    log->trace_enabled = (getenv ("MONGOCRYPT_TRACE") != NULL);
31 #endif
32 }
33 
34 
35 void
_mongocrypt_log_cleanup(_mongocrypt_log_t * log)36 _mongocrypt_log_cleanup (_mongocrypt_log_t *log)
37 {
38    _mongocrypt_mutex_cleanup (&log->mutex);
39    memset (log, 0, sizeof (*log));
40 }
41 
42 void
_mongocrypt_stdout_log_fn(mongocrypt_log_level_t level,const char * message,uint32_t message_len,void * ctx)43 _mongocrypt_stdout_log_fn (mongocrypt_log_level_t level,
44                            const char *message,
45                            uint32_t message_len,
46                            void *ctx)
47 {
48    switch (level) {
49    case MONGOCRYPT_LOG_LEVEL_FATAL:
50       printf ("FATAL");
51       break;
52    case MONGOCRYPT_LOG_LEVEL_ERROR:
53       printf ("ERROR");
54       break;
55    case MONGOCRYPT_LOG_LEVEL_WARNING:
56       printf ("WARNING");
57       break;
58    case MONGOCRYPT_LOG_LEVEL_INFO:
59       printf ("INFO");
60       break;
61    case MONGOCRYPT_LOG_LEVEL_TRACE:
62       printf ("TRACE");
63       break;
64    }
65    printf (" %s\n", message);
66 }
67 
68 
69 void
_mongocrypt_log_set_fn(_mongocrypt_log_t * log,mongocrypt_log_fn_t fn,void * ctx)70 _mongocrypt_log_set_fn (_mongocrypt_log_t *log,
71                         mongocrypt_log_fn_t fn,
72                         void *ctx)
73 {
74    _mongocrypt_mutex_lock (&log->mutex);
75    log->fn = fn;
76    log->ctx = ctx;
77    _mongocrypt_mutex_unlock (&log->mutex);
78 }
79 
80 
81 void
_mongocrypt_log(_mongocrypt_log_t * log,mongocrypt_log_level_t level,const char * format,...)82 _mongocrypt_log (_mongocrypt_log_t *log,
83                  mongocrypt_log_level_t level,
84                  const char *format,
85                  ...)
86 {
87    va_list args;
88    char *message;
89 
90    if (level == MONGOCRYPT_LOG_LEVEL_TRACE && !log->trace_enabled) {
91       return;
92    }
93 
94    BSON_ASSERT (format);
95 
96    va_start (args, format);
97    message = bson_strdupv_printf (format, args);
98    va_end (args);
99 
100    BSON_ASSERT (message);
101 
102    _mongocrypt_mutex_lock (&log->mutex);
103    if (log->fn) {
104       log->fn (level, message, (uint32_t) strlen (message), log->ctx);
105    }
106    _mongocrypt_mutex_unlock (&log->mutex);
107    bson_free (message);
108 }
109