| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -92,6 +92,8 @@ bool mpw_push_string(uint8_t **buffer, size_t *bufferSize, const char *pushStrin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool mpw_string_push(char **string, const char *pushString) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!string || !pushString)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!*string)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        *string = calloc( 1, sizeof( char ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -103,10 +105,8 @@ bool mpw_string_pushf(char **string, const char *pushFormat, ...) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_list args;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_start( args, pushFormat );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    char *pushString = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool success = vasprintf( &pushString, pushFormat, args ) >= 0 && mpw_string_push( string, pushString );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool success = mpw_string_push( string, mpw_vstr( pushFormat, args ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_end( args );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    mpw_free_string( &pushString );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return success;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -344,24 +344,31 @@ bool mpw_id_buf_equals(const char *id1, const char *id2) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static char *str_str;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const char *mpw_str(const char *format, ...) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_list args;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_start( args, format );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    vasprintf( &str_str, format, args );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const char *str_str = mpw_vstr( format, args );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    va_end( args );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return str_str;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static char **mpw_hex_buf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static unsigned int mpw_hex_buf_i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const char *mpw_vstr(const char *format, va_list args) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // TODO: We should find a way to get rid of this shared storage medium.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // FIXME: Not thread-safe
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    static char *str_str;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return vasprintf( &str_str, format, args ) < 0? NULL: str_str;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const char *mpw_hex(const void *buf, size_t length) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // TODO: We should find a way to get rid of this shared storage medium.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // FIXME: Not thread-safe
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    static char **mpw_hex_buf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    static unsigned int mpw_hex_buf_i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!mpw_hex_buf)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        mpw_hex_buf = calloc( 10, sizeof( char * ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -383,30 +390,50 @@ const char *mpw_hex_l(uint32_t number) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return mpw_hex( &buf, sizeof( buf ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifdef COLOR
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int putvari;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static char *putvarc = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int termsetup;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int initputvar() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!isatty(STDERR_FILENO))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (putvarc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        free( putvarc );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#if MPW_COLOR
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static char *str_tputs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int str_tputs_cursor;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static const int str_tputs_max = 256;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static bool mpw_setupterm() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!isatty( STDERR_FILENO ))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    static bool termsetup;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!termsetup) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        int status;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (! (termsetup = (setupterm( NULL, STDERR_FILENO, &status ) == 0 && status == 1))) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            wrn( "Terminal doesn't support color (setupterm errno %d).\n", status );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        int errret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!(termsetup = (setupterm( NULL, STDERR_FILENO, &errret ) == OK))) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            wrn( "Terminal doesn't support color (setupterm errret %d).\n", errret );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    putvarc=(char *)calloc(256, sizeof(char));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    putvari=0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int putvar(int c) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    putvarc[putvari++]=c;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static int mpw_tputc(int c) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (++str_tputs_cursor < str_tputs_max) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        str_tputs[str_tputs_cursor] = (char)c;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return OK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return ERR;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static char *mpw_tputs(const char *str, int affcnt) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (str_tputs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        mpw_free( &str_tputs, str_tputs_max );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    str_tputs = calloc( str_tputs_max, sizeof( char ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    str_tputs_cursor = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    char *result = tputs( str, affcnt, mpw_tputc ) == ERR? NULL: strndup( str_tputs, str_tputs_max );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (str_tputs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        mpw_free( &str_tputs, str_tputs_max );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return result;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -421,23 +448,20 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "♨", "♩", "♪", "♫", "⚐", "⚑", "⚔", "⚖", "⚙", "⚠", "⌘", "⏎", "✄", "✆", "✈", "✉", "✌"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const uint8_t *identiconSeed = mpw_hash_hmac_sha256( (const uint8_t *)masterPassword, strlen( masterPassword ),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            (const uint8_t *)fullName,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            strlen( fullName ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    const uint8_t *identiconSeed = mpw_hash_hmac_sha256(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            (const uint8_t *)masterPassword, strlen( masterPassword ),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            (const uint8_t *)fullName, strlen( fullName ) );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!identiconSeed)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    char *colorString, *resetString;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifdef COLOR
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (initputvar()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifdef MPW_COLOR
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (mpw_setupterm()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        uint8_t colorIdentifier = (uint8_t)(identiconSeed[4] % 7 + 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tputs(tparm(tgetstr("AF", NULL), colorIdentifier), 1, putvar);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        colorString = calloc(strlen(putvarc) + 1, sizeof(char));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        strcpy(colorString, putvarc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        tputs(tgetstr("me", NULL), 1, putvar);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        resetString = calloc(strlen(putvarc) + 1, sizeof(char));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        strcpy(resetString, putvarc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    } else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        colorString = mpw_tputs( tparm( tgetstr( "AF", NULL ), colorIdentifier ), 1 );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        resetString = mpw_tputs( tgetstr( "me", NULL ), 1 );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        colorString = calloc( 1, sizeof( char ) );
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -454,8 +478,7 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            resetString );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    mpw_free( &identiconSeed, 32 );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    free( colorString );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    free( resetString );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    mpw_free_strings( &colorString, &resetString, NULL );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return identicon;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |