sim: Allow Rust logging level to control C logging

Change the C logging code, when in the simulator, to query what the rust
logging level is set to.  This allows the level of logging from the C
code to be set through the environment.  For example

    RUST_LOG=bootsim=info cargo run --release runall

will enable logging at the "info" level for all of the C code as well as
the simulator code.  The C code's logging can be selected specifically
by using bootsim::api instead of just bootsim in the above.
diff --git a/boot/bootutil/include/bootutil/bootutil_log.h b/boot/bootutil/include/bootutil/bootutil_log.h
index 3cd03a3..e889397 100644
--- a/boot/bootutil/include/bootutil/bootutil_log.h
+++ b/boot/bootutil/include/bootutil/bootutil_log.h
@@ -78,30 +78,48 @@
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
 #endif
 
+int sim_log_enabled(int level);
+
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_ERROR
-#define BOOT_LOG_ERR(_fmt, ...)						\
-    do { printf("[ERR] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_ERR(_fmt, ...)                                         \
+    do {                                                                \
+        if (sim_log_enabled(BOOT_LOG_LEVEL_ERROR)) {                    \
+            printf("[ERR] " _fmt "\n", ##__VA_ARGS__);                  \
+        }                                                               \
+    } while (0)
 #else
 #define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_WARNING
-#define BOOT_LOG_WRN(_fmt, ...)                                               \
-    do { printf("[WRN] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_WRN(_fmt, ...)                                         \
+    do {                                                                \
+        if (sim_log_enabled(BOOT_LOG_LEVEL_WARNING)) {                  \
+            printf("[WRN] " _fmt "\n", ##__VA_ARGS__);                  \
+        }                                                               \
+    } while (0)
 #else
 #define BOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_INFO
-#define BOOT_LOG_INF(_fmt, ...)                                               \
-    do { printf("[INF] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_INF(_fmt, ...)                                         \
+    do {                                                                \
+        if (sim_log_enabled(BOOT_LOG_LEVEL_INFO)) {                     \
+            printf("[WRN] " _fmt "\n", ##__VA_ARGS__);                  \
+        }                                                               \
+    } while (0)
 #else
 #define BOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_DEBUG
-#define BOOT_LOG_DBG(_fmt, ...)                                               \
-    do { printf("[DBG] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_DBG(_fmt, ...)                                         \
+    do {                                                                \
+        if (sim_log_enabled(BOOT_LOG_LEVEL_DEBUG)) {                    \
+            printf("[DBG] " _fmt "\n", ##__VA_ARGS__);                  \
+        }                                                               \
+    } while (0)
 #else
 #define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
 #endif
diff --git a/sim/src/api.rs b/sim/src/api.rs
index ec502a2..21806ce 100644
--- a/sim/src/api.rs
+++ b/sim/src/api.rs
@@ -2,6 +2,7 @@
 
 use flash::{Result, Flash};
 use libc;
+use log::LogLevel;
 use std::slice;
 
 // This isn't meant to call directly, but by a wrapper.
@@ -35,3 +36,25 @@
         },
     }
 }
+
+/// Called by C code to determine if we should log at this level.  Levels are defined in
+/// bootutil/bootutil_log.h.  This makes the logging from the C code controlled by bootsim::api, so
+/// for example, it can be enabled with something like:
+///     RUST_LOG=bootsim::api=info cargo run --release runall
+/// or
+///     RUST_LOG=bootsim=info cargo run --release runall
+#[no_mangle]
+pub extern fn sim_log_enabled(level: libc::c_int) -> libc::c_int {
+    let res = match level {
+        1 => log_enabled!(LogLevel::Error),
+        2 => log_enabled!(LogLevel::Warn),
+        3 => log_enabled!(LogLevel::Info),
+        4 => log_enabled!(LogLevel::Trace),
+        _ => false,
+    };
+    if res {
+        1
+    } else {
+        0
+    }
+}