Log native mpw into Java.
This commit is contained in:
		@@ -714,7 +714,7 @@ void cli_mpw(Arguments *args, Operation *operation) {
 | 
			
		||||
    if (!operation->site)
 | 
			
		||||
        abort();
 | 
			
		||||
 | 
			
		||||
    if (mpw_verbosity >= inf_level)
 | 
			
		||||
    if (mpw_verbosity >= LogLevelInfo)
 | 
			
		||||
        fprintf( stderr, "%s's %s for %s:\n[ %s ]: ",
 | 
			
		||||
                operation->file->user->fullName, operation->purposeResult, operation->site->siteName, operation->identicon );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,12 +31,12 @@ library {
 | 
			
		||||
    toolChains {
 | 
			
		||||
        withType( VisualCpp ) {
 | 
			
		||||
            eachPlatform {
 | 
			
		||||
                cppCompiler.withArguments { addAll( ['/TC', '/MT', '/Ox', '/DMPW_SODIUM=1', '/DSODIUM_STATIC', '/DSODIUM_EXPORT='] ) }
 | 
			
		||||
                cppCompiler.withArguments { addAll( ['/TC', '/MT', '/Ox', '/DMPW_SODIUM=1', '/DSODIUM_STATIC', '/DSODIUM_EXPORT=', '/DMPW_LOG=mpw_log_app'] ) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        withType( GccCompatibleToolChain ) {
 | 
			
		||||
            eachPlatform {
 | 
			
		||||
                cppCompiler.withArguments { addAll( ['-x', 'c', '-O3', '-Werror', '-DMPW_SODIUM=1'] ) }
 | 
			
		||||
                cppCompiler.withArguments { addAll( ['-x', 'c', '-O3', '-Werror', '-DMPW_SODIUM=1', '-DMPW_LOG=mpw_log_app'] ) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,67 @@
 | 
			
		||||
 | 
			
		||||
// TODO: We may need to zero the jbytes safely.
 | 
			
		||||
 | 
			
		||||
static jobject logger;
 | 
			
		||||
static JNIEnv *env;
 | 
			
		||||
 | 
			
		||||
void mpw_log_app(LogLevel level, const char *format, ...) {
 | 
			
		||||
    jmethodID method = NULL;
 | 
			
		||||
    jclass class = (*env)->GetObjectClass( env, logger );
 | 
			
		||||
    if (level >= LogLevelTrace)
 | 
			
		||||
        method = (*env)->GetMethodID( env, class, "trace", "(Ljava/lang/String;)V" );
 | 
			
		||||
    else if (level == LogLevelDebug)
 | 
			
		||||
        method = (*env)->GetMethodID( env, class, "debug", "(Ljava/lang/String;)V" );
 | 
			
		||||
    else if (level == LogLevelInfo)
 | 
			
		||||
        method = (*env)->GetMethodID( env, class, "info", "(Ljava/lang/String;)V" );
 | 
			
		||||
    else if (level == LogLevelWarning)
 | 
			
		||||
        method = (*env)->GetMethodID( env, class, "warn", "(Ljava/lang/String;)V" );
 | 
			
		||||
    else if (level <= LogLevelError)
 | 
			
		||||
        method = (*env)->GetMethodID( env, class, "error", "(Ljava/lang/String;)V" );
 | 
			
		||||
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start( args, format );
 | 
			
		||||
 | 
			
		||||
    if (class && method && logger) {
 | 
			
		||||
        char *message = NULL;
 | 
			
		||||
        int length = vasprintf(&message, format, args);
 | 
			
		||||
        if (length > 0)
 | 
			
		||||
            (*env)->CallVoidMethod(env, logger, method, (*env)->NewStringUTF( env, message ));
 | 
			
		||||
        if (message)
 | 
			
		||||
            mpw_free(&message, (size_t) length);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        // Can't log via slf4j, fall back to cli logger.
 | 
			
		||||
        mpw_vlog_cli( level, format, args );
 | 
			
		||||
 | 
			
		||||
    va_end( args );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
 | 
			
		||||
    JNIEnv* env;
 | 
			
		||||
    if ((*vm)->GetEnv( vm, (void **)&env, JNI_VERSION_1_6 ) != JNI_OK)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    jclass class = (*env)->FindClass( env, "org/slf4j/LoggerFactory" );
 | 
			
		||||
    jmethodID method = (*env)->GetStaticMethodID( env, class, "getLogger", "(Ljava/lang/String;)Lorg/slf4j/Logger;" );
 | 
			
		||||
    jstring name = (*env)->NewStringUTF( env, "com.lyndir.masterpassword.algorithm" );
 | 
			
		||||
    if (class && method && name)
 | 
			
		||||
        logger = (*env)->CallStaticObjectMethod( env, class, method, name );
 | 
			
		||||
    else
 | 
			
		||||
        wrn( "Couldn't initialize JNI logger." );
 | 
			
		||||
 | 
			
		||||
    class = (*env)->GetObjectClass( env, logger );
 | 
			
		||||
    if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isTraceEnabled", "()Z" ) ))
 | 
			
		||||
        mpw_verbosity = LogLevelTrace;
 | 
			
		||||
    else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isDebugEnabled", "()Z" ) ))
 | 
			
		||||
        mpw_verbosity = LogLevelDebug;
 | 
			
		||||
    else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isInfoEnabled", "()Z" ) ))
 | 
			
		||||
        mpw_verbosity = LogLevelInfo;
 | 
			
		||||
    else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isWarnEnabled", "()Z" ) ))
 | 
			
		||||
        mpw_verbosity = LogLevelWarning;
 | 
			
		||||
    else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isErrorEnabled", "()Z" ) ))
 | 
			
		||||
        mpw_verbosity = LogLevelError;
 | 
			
		||||
    else
 | 
			
		||||
        mpw_verbosity = LogLevelFatal;
 | 
			
		||||
 | 
			
		||||
    return JNI_VERSION_1_6;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,53 @@ MP_LIBS_BEGIN
 | 
			
		||||
#include "aes.h"
 | 
			
		||||
MP_LIBS_END
 | 
			
		||||
 | 
			
		||||
#ifdef inf_level
 | 
			
		||||
int mpw_verbosity = inf_level;
 | 
			
		||||
#endif
 | 
			
		||||
int mpw_verbosity = LogLevelInfo;
 | 
			
		||||
FILE *mpw_log_cli_file;
 | 
			
		||||
 | 
			
		||||
void mpw_log_cli(LogLevel level, const char *format, ...) {
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start( args, format );
 | 
			
		||||
    mpw_vlog_cli( level, format, args );
 | 
			
		||||
    va_end( args );
 | 
			
		||||
}
 | 
			
		||||
void mpw_vlog_cli(LogLevel level, const char *format, va_list args) {
 | 
			
		||||
    if (!mpw_log_cli_file)
 | 
			
		||||
        mpw_log_cli_file = stderr;
 | 
			
		||||
 | 
			
		||||
    if (mpw_verbosity >= level) {
 | 
			
		||||
        if (mpw_verbosity >= LogLevelDebug) {
 | 
			
		||||
            switch (level) {
 | 
			
		||||
                case LogLevelTrace:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[TRC] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                case LogLevelDebug:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[DBG] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                case LogLevelInfo:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[INF] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                case LogLevelWarning:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[WRN] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                case LogLevelError:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[ERR] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                case LogLevelFatal:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[FTL] " );
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    fprintf( mpw_log_cli_file, "[???] " );
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vfprintf( mpw_log_cli_file, format, args );
 | 
			
		||||
        fprintf( mpw_log_cli_file, "\n" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (level <= LogLevelFatal)
 | 
			
		||||
        abort();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mpw_uint16(const uint16_t number, uint8_t buf[2]) {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,48 +27,42 @@ MP_LIBS_BEGIN
 | 
			
		||||
MP_LIBS_END
 | 
			
		||||
 | 
			
		||||
//// Logging.
 | 
			
		||||
typedef mpw_enum(int, LogLevel) {
 | 
			
		||||
    /** Logging internal state. */
 | 
			
		||||
    LogLevelTrace = 3,
 | 
			
		||||
    /** Logging state and events interesting when investigating issues. */
 | 
			
		||||
    LogLevelDebug = 2,
 | 
			
		||||
    /** User messages. */
 | 
			
		||||
    LogLevelInfo = 1,
 | 
			
		||||
    /** Recoverable issues and user suggestions. */
 | 
			
		||||
    LogLevelWarning = 0,
 | 
			
		||||
    /** Unrecoverable issues. */
 | 
			
		||||
    LogLevelError = -1,
 | 
			
		||||
    /** Issues that lead to abortion. */
 | 
			
		||||
    LogLevelFatal = -2,
 | 
			
		||||
};
 | 
			
		||||
LogLevel mpw_verbosity;
 | 
			
		||||
 | 
			
		||||
/** mpw_log_cli is a sink that writes log messages to the mpw_log_cli_file, which defaults to stderr. */
 | 
			
		||||
FILE *mpw_log_cli_file;
 | 
			
		||||
void mpw_log_cli(LogLevel level, const char *format, ...);
 | 
			
		||||
void mpw_vlog_cli(LogLevel level, const char *format, va_list args);
 | 
			
		||||
 | 
			
		||||
/** mpw_log_app is a sink placeholder that an application can implement to consume log messages. */
 | 
			
		||||
void mpw_log_app(LogLevel level, const char *format, ...);
 | 
			
		||||
 | 
			
		||||
/** The sink you want to channel the log messages into, defaults to mpw_log_cli. */
 | 
			
		||||
#ifndef MPW_LOG
 | 
			
		||||
#define MPW_LOG mpw_log_cli
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef trc
 | 
			
		||||
extern int mpw_verbosity;
 | 
			
		||||
 | 
			
		||||
#ifndef mpw_log_do
 | 
			
		||||
#define mpw_log_do(level, format, ...) \
 | 
			
		||||
    fprintf( stderr, format "\n", ##__VA_ARGS__ )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef mpw_log
 | 
			
		||||
#define mpw_log(level, format, ...) do { \
 | 
			
		||||
        if (mpw_verbosity >= level) { \
 | 
			
		||||
            mpw_log_do( level, format, ##__VA_ARGS__ ); \
 | 
			
		||||
        } \
 | 
			
		||||
        if (level <= -2) { \
 | 
			
		||||
            abort(); \
 | 
			
		||||
        } \
 | 
			
		||||
    } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Logging internal state. */
 | 
			
		||||
#define trc_level 3
 | 
			
		||||
#define trc(format, ...) mpw_log( trc_level, format, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
/** Logging state and events interesting when investigating issues. */
 | 
			
		||||
#define dbg_level 2
 | 
			
		||||
#define dbg(format, ...) mpw_log( dbg_level, format, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
/** User messages. */
 | 
			
		||||
#define inf_level 1
 | 
			
		||||
#define inf(format, ...) mpw_log( inf_level, format, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
/** Recoverable issues and user suggestions. */
 | 
			
		||||
#define wrn_level 0
 | 
			
		||||
#define wrn(format, ...) mpw_log( wrn_level, format, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
/** Unrecoverable issues. */
 | 
			
		||||
#define err_level -1
 | 
			
		||||
#define err(format, ...) mpw_log( err_level, format, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
/** Issues that lead to abortion. */
 | 
			
		||||
#define ftl_level -2
 | 
			
		||||
#define ftl(format, ...) mpw_log( ftl_level, format, ##__VA_ARGS__ )
 | 
			
		||||
#define trc(format, ...) MPW_LOG( LogLevelTrace, format, ##__VA_ARGS__ )
 | 
			
		||||
#define dbg(format, ...) MPW_LOG( LogLevelDebug, format, ##__VA_ARGS__ )
 | 
			
		||||
#define inf(format, ...) MPW_LOG( LogLevelInfo, format, ##__VA_ARGS__ )
 | 
			
		||||
#define wrn(format, ...) MPW_LOG( LogLevelWarning, format, ##__VA_ARGS__ )
 | 
			
		||||
#define err(format, ...) MPW_LOG( LogLevelError, format, ##__VA_ARGS__ )
 | 
			
		||||
#define ftl(format, ...) MPW_LOG( LogLevelFatal, format, ##__VA_ARGS__ )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef min
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user