Huge refactor to do marshalling completely through mpw data object now.
This commit is contained in:
		@@ -565,7 +565,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
 | 
				
			|||||||
           saveInContext:(NSManagedObjectContext *)context {
 | 
					           saveInContext:(NSManagedObjectContext *)context {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Read metadata for the import file.
 | 
					    // Read metadata for the import file.
 | 
				
			||||||
    MPMarshalledInfo *info = mpw_marshal_read_info( importData.UTF8String );
 | 
					    MPMarshalledInfo *info = mpw_marshal_read( importData.UTF8String );
 | 
				
			||||||
    if (info->format == MPMarshalFormatNone)
 | 
					    if (info->format == MPMarshalFormatNone)
 | 
				
			||||||
        return MPError( ([NSError errorWithDomain:MPErrorDomain code:MPErrorMarshalCode userInfo:@{
 | 
					        return MPError( ([NSError errorWithDomain:MPErrorDomain code:MPErrorMarshalCode userInfo:@{
 | 
				
			||||||
                @"type"                  : @(MPMarshalErrorFormat),
 | 
					                @"type"                  : @(MPMarshalErrorFormat),
 | 
				
			||||||
@@ -589,7 +589,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Parse import data.
 | 
					    // Parse import data.
 | 
				
			||||||
    MPMarshalError importError = { .type = MPMarshalSuccess };
 | 
					    MPMarshalError importError = { .type = MPMarshalSuccess };
 | 
				
			||||||
    MPMarshalledUser *importUser = mpw_marshal_read( importData.UTF8String, info->format, importMasterPassword.UTF8String, &importError );
 | 
					    MPMarshalledUser *importUser = mpw_marshal_auth( importData.UTF8String, info->format, importMasterPassword.UTF8String, &importError );
 | 
				
			||||||
    mpw_marshal_info_free( &info );
 | 
					    mpw_marshal_info_free( &info );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @try {
 | 
					    @try {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,6 +157,7 @@ typedef struct {
 | 
				
			|||||||
    const char *resultState;
 | 
					    const char *resultState;
 | 
				
			||||||
    const char *resultParam;
 | 
					    const char *resultParam;
 | 
				
			||||||
    MPMarshalledFile *file;
 | 
					    MPMarshalledFile *file;
 | 
				
			||||||
 | 
					    MPMarshalledUser *user;
 | 
				
			||||||
    MPMarshalledSite *site;
 | 
					    MPMarshalledSite *site;
 | 
				
			||||||
    MPMarshalledQuestion *question;
 | 
					    MPMarshalledQuestion *question;
 | 
				
			||||||
} Operation;
 | 
					} Operation;
 | 
				
			||||||
@@ -233,8 +234,8 @@ int main(const int argc, char *const argv[]) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Operation summary.
 | 
					    // Operation summary.
 | 
				
			||||||
    dbg( "-----------------" );
 | 
					    dbg( "-----------------" );
 | 
				
			||||||
    if (operation.file && operation.file->user) {
 | 
					    if (operation.file && operation.user) {
 | 
				
			||||||
        dbg( "fullName         : %s", operation.file->user->fullName );
 | 
					        dbg( "fullName         : %s", operation.user->fullName );
 | 
				
			||||||
        dbg( "identicon        : %s", operation.identicon );
 | 
					        dbg( "identicon        : %s", operation.identicon );
 | 
				
			||||||
        dbg( "sitesFormat      : %s%s", mpw_format_name( operation.sitesFormat ), operation.sitesFormatFixed? " (fixed)": "" );
 | 
					        dbg( "sitesFormat      : %s%s", mpw_format_name( operation.sitesFormat ), operation.sitesFormatFixed? " (fixed)": "" );
 | 
				
			||||||
        dbg( "sitesPath        : %s", operation.sitesPath );
 | 
					        dbg( "sitesPath        : %s", operation.sitesPath );
 | 
				
			||||||
@@ -273,6 +274,7 @@ void cli_free(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        mpw_free_strings( &operation->keyContext, &operation->resultState, &operation->resultParam, NULL );
 | 
					        mpw_free_strings( &operation->keyContext, &operation->resultState, &operation->resultParam, NULL );
 | 
				
			||||||
        mpw_free_strings( &operation->identicon, &operation->sitesPath, NULL );
 | 
					        mpw_free_strings( &operation->identicon, &operation->sitesPath, NULL );
 | 
				
			||||||
        mpw_marshal_file_free( &operation->file );
 | 
					        mpw_marshal_file_free( &operation->file );
 | 
				
			||||||
 | 
					        mpw_marshal_user_free( &operation->user );
 | 
				
			||||||
        operation->site = NULL;
 | 
					        operation->site = NULL;
 | 
				
			||||||
        operation->question = NULL;
 | 
					        operation->question = NULL;
 | 
				
			||||||
        cli_masterKeyProvider_free();
 | 
					        cli_masterKeyProvider_free();
 | 
				
			||||||
@@ -488,8 +490,9 @@ void cli_user(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        // If no user from mpsites, create a new one.
 | 
					        // If no user from mpsites, create a new one.
 | 
				
			||||||
        mpw_free_string( &operation->sitesPath );
 | 
					        mpw_free_string( &operation->sitesPath );
 | 
				
			||||||
        mpw_marshal_file_free( &operation->file );
 | 
					        mpw_marshal_file_free( &operation->file );
 | 
				
			||||||
        operation->file = mpw_marshal_file( NULL, mpw_marshal_user(
 | 
					        mpw_marshal_user_free( &operation->user );
 | 
				
			||||||
                operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent ), NULL );
 | 
					        operation->file = mpw_marshal_file( NULL, NULL, NULL );
 | 
				
			||||||
 | 
					        operation->user = mpw_marshal_user( operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
@@ -500,42 +503,44 @@ void cli_user(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        fclose( sitesFile );
 | 
					        fclose( sitesFile );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Parse file.
 | 
					        // Parse file.
 | 
				
			||||||
        MPMarshalError marshalError = { .type = MPMarshalSuccess };
 | 
					 | 
				
			||||||
        mpw_marshal_file_free( &operation->file );
 | 
					        mpw_marshal_file_free( &operation->file );
 | 
				
			||||||
        operation->file = mpw_marshal_read( sitesInputData,
 | 
					        mpw_marshal_user_free( &operation->user );
 | 
				
			||||||
                cli_masterKeyProvider_op( operation ), &marshalError );
 | 
					        operation->file = mpw_marshal_read( NULL, sitesInputData );
 | 
				
			||||||
        if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) {
 | 
					        if (operation->file && operation->file->error.type == MPMarshalSuccess) {
 | 
				
			||||||
            // Update master password in mpsites.
 | 
					            operation->user = mpw_marshal_auth( operation->file, cli_masterKeyProvider_op( operation ) );
 | 
				
			||||||
            while (marshalError.type == MPMarshalErrorMasterPassword) {
 | 
					 | 
				
			||||||
                inf( "Given master password does not match configuration." );
 | 
					 | 
				
			||||||
                inf( "To update the configuration with this new master password, first confirm the old master password." );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const char *importMasterPassword = NULL;
 | 
					            if (operation->file->error.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) {
 | 
				
			||||||
                while (!importMasterPassword || !strlen( importMasterPassword )) {
 | 
					                // Update master password in mpsites.
 | 
				
			||||||
 | 
					                while (operation->file->error.type == MPMarshalErrorMasterPassword) {
 | 
				
			||||||
 | 
					                    inf( "Given master password does not match configuration." );
 | 
				
			||||||
 | 
					                    inf( "To update the configuration with this new master password, first confirm the old master password." );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const char *importMasterPassword = NULL;
 | 
				
			||||||
 | 
					                    while (!importMasterPassword || !strlen( importMasterPassword )) {
 | 
				
			||||||
 | 
					                        mpw_free_string( &importMasterPassword );
 | 
				
			||||||
 | 
					                        importMasterPassword = mpw_getpass( "Old master password: " );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    mpw_marshal_user_free( &operation->user );
 | 
				
			||||||
 | 
					                    operation->user = mpw_marshal_auth( operation->file, cli_masterKeyProvider_str( importMasterPassword ) );
 | 
				
			||||||
 | 
					                    if (operation->file && operation->user)
 | 
				
			||||||
 | 
					                        operation->user->masterKeyProvider = cli_masterKeyProvider_op( operation );
 | 
				
			||||||
                    mpw_free_string( &importMasterPassword );
 | 
					                    mpw_free_string( &importMasterPassword );
 | 
				
			||||||
                    importMasterPassword = mpw_getpass( "Old master password: " );
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                mpw_marshal_file_free( &operation->file );
 | 
					 | 
				
			||||||
                operation->file = mpw_marshal_read( sitesInputData,
 | 
					 | 
				
			||||||
                        cli_masterKeyProvider_str( importMasterPassword ), &marshalError );
 | 
					 | 
				
			||||||
                if (operation->file && operation->file->user)
 | 
					 | 
				
			||||||
                    operation->file->user->masterKeyProvider = cli_masterKeyProvider_op( operation );
 | 
					 | 
				
			||||||
                mpw_free_string( &importMasterPassword );
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mpw_free_string( &sitesInputData );
 | 
					        mpw_free_string( &sitesInputData );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Incorrect master password.
 | 
					        // Incorrect master password.
 | 
				
			||||||
        if (marshalError.type == MPMarshalErrorMasterPassword) {
 | 
					        if (operation->file->error.type == MPMarshalErrorMasterPassword) {
 | 
				
			||||||
            ftl( "Incorrect master password according to configuration:\n  %s: %s", operation->sitesPath, marshalError.message );
 | 
					            ftl( "Incorrect master password according to configuration:\n  %s: %s", operation->sitesPath, operation->file->error.message );
 | 
				
			||||||
            cli_free( args, operation );
 | 
					            cli_free( args, operation );
 | 
				
			||||||
            exit( EX_DATAERR );
 | 
					            exit( EX_DATAERR );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Any other parse error.
 | 
					        // Any other parse error.
 | 
				
			||||||
        if (!operation->file || !operation->file->user || marshalError.type != MPMarshalSuccess) {
 | 
					        if (!operation->file || !operation->user || operation->file->error.type != MPMarshalSuccess) {
 | 
				
			||||||
            err( "Couldn't parse configuration file:\n  %s: %s", operation->sitesPath, marshalError.message );
 | 
					            err( "Couldn't parse configuration file:\n  %s: %s", operation->sitesPath, operation->file->error.message );
 | 
				
			||||||
            cli_free( args, operation );
 | 
					            cli_free( args, operation );
 | 
				
			||||||
            exit( EX_DATAERR );
 | 
					            exit( EX_DATAERR );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -548,7 +553,7 @@ void cli_site(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Load the site object from mpsites.
 | 
					    // Load the site object from mpsites.
 | 
				
			||||||
    MPMarshalledUser *user = operation->file->user;
 | 
					    MPMarshalledUser *user = operation->user;
 | 
				
			||||||
    for (size_t s = 0; !operation->site && s < user->sites_count; ++s)
 | 
					    for (size_t s = 0; !operation->site && s < user->sites_count; ++s)
 | 
				
			||||||
        if (strcmp( operation->siteName, (&user->sites[s])->siteName ) == OK)
 | 
					        if (strcmp( operation->siteName, (&user->sites[s])->siteName ) == OK)
 | 
				
			||||||
            operation->site = &user->sites[s];
 | 
					            operation->site = &user->sites[s];
 | 
				
			||||||
@@ -588,8 +593,8 @@ void cli_question(Arguments *args, Operation *operation) {
 | 
				
			|||||||
void cli_operation(Arguments *args, Operation *operation) {
 | 
					void cli_operation(Arguments *args, Operation *operation) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mpw_free_string( &operation->identicon );
 | 
					    mpw_free_string( &operation->identicon );
 | 
				
			||||||
    operation->file->user->identicon = mpw_identicon( operation->file->user->fullName, operation->masterPassword );
 | 
					    operation->user->identicon = mpw_identicon( operation->user->fullName, operation->masterPassword );
 | 
				
			||||||
    operation->identicon = mpw_identicon_render( operation->file->user->identicon );
 | 
					    operation->identicon = mpw_identicon_render( operation->user->identicon );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!operation->site)
 | 
					    if (!operation->site)
 | 
				
			||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
@@ -703,9 +708,9 @@ void cli_algorithmVersion(Arguments *args, Operation *operation) {
 | 
				
			|||||||
void cli_sitesRedacted(Arguments *args, Operation *operation) {
 | 
					void cli_sitesRedacted(Arguments *args, Operation *operation) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (args->sitesRedacted)
 | 
					    if (args->sitesRedacted)
 | 
				
			||||||
        operation->file->user->redacted = strcmp( args->sitesRedacted, "1" ) == OK;
 | 
					        operation->user->redacted = strcmp( args->sitesRedacted, "1" ) == OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if (!operation->file->user->redacted)
 | 
					    else if (!operation->user->redacted)
 | 
				
			||||||
        wrn( "Sites configuration is not redacted.  Use -R 1 to change this." );
 | 
					        wrn( "Sites configuration is not redacted.  Use -R 1 to change this." );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -716,21 +721,21 @@ void cli_mpw(Arguments *args, Operation *operation) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (mpw_verbosity >= LogLevelInfo)
 | 
					    if (mpw_verbosity >= LogLevelInfo)
 | 
				
			||||||
        fprintf( stderr, "%s's %s for %s:\n[ %s ]: ",
 | 
					        fprintf( stderr, "%s's %s for %s:\n[ %s ]: ",
 | 
				
			||||||
                operation->file->user->fullName, operation->purposeResult, operation->site->siteName, operation->identicon );
 | 
					                operation->user->fullName, operation->purposeResult, operation->site->siteName, operation->identicon );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Determine master key.
 | 
					    // Determine master key.
 | 
				
			||||||
    MPMasterKey masterKey = NULL;
 | 
					    MPMasterKey masterKey = NULL;
 | 
				
			||||||
    if (operation->file->user->masterKeyProvider)
 | 
					    if (operation->user->masterKeyProvider)
 | 
				
			||||||
        masterKey = operation->file->user->masterKeyProvider( operation->site->algorithm, operation->file->user->fullName );
 | 
					        masterKey = operation->user->masterKeyProvider( operation->site->algorithm, operation->user->fullName );
 | 
				
			||||||
    if (!masterKey) {
 | 
					    if (!masterKey) {
 | 
				
			||||||
        ftl( "Couldn't derive master key." );
 | 
					        ftl( "Couldn't derive master key." );
 | 
				
			||||||
        cli_free( args, operation );
 | 
					        cli_free( args, operation );
 | 
				
			||||||
        exit( EX_SOFTWARE );
 | 
					        exit( EX_SOFTWARE );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    MPKeyID keyID = mpw_id_buf( masterKey, MPMasterKeySize );
 | 
					    MPKeyID keyID = mpw_id_buf( masterKey, MPMasterKeySize );
 | 
				
			||||||
    if (!operation->file->user->keyID)
 | 
					    if (!operation->user->keyID)
 | 
				
			||||||
        operation->file->user->keyID = mpw_strdup( keyID );
 | 
					        operation->user->keyID = mpw_strdup( keyID );
 | 
				
			||||||
    else if (!mpw_id_buf_equals( keyID, operation->file->user->keyID )) {
 | 
					    else if (!mpw_id_buf_equals( keyID, operation->user->keyID )) {
 | 
				
			||||||
        ftl( "Master key mismatch." );
 | 
					        ftl( "Master key mismatch." );
 | 
				
			||||||
        cli_free( args, operation );
 | 
					        cli_free( args, operation );
 | 
				
			||||||
        exit( EX_SOFTWARE );
 | 
					        exit( EX_SOFTWARE );
 | 
				
			||||||
@@ -792,12 +797,15 @@ void cli_mpw(Arguments *args, Operation *operation) {
 | 
				
			|||||||
    mpw_free_string( &result );
 | 
					    mpw_free_string( &result );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update usage metadata.
 | 
					    // Update usage metadata.
 | 
				
			||||||
    operation->site->lastUsed = operation->file->user->lastUsed = time( NULL );
 | 
					    operation->site->lastUsed = operation->user->lastUsed = time( NULL );
 | 
				
			||||||
    operation->site->uses++;
 | 
					    operation->site->uses++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cli_save(Arguments *args, Operation *operation) {
 | 
					void cli_save(Arguments *args, Operation *operation) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!operation->file || !operation->user)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!operation->sitesFormatFixed)
 | 
					    if (!operation->sitesFormatFixed)
 | 
				
			||||||
        operation->sitesFormat = MPMarshalFormatDefault;
 | 
					        operation->sitesFormat = MPMarshalFormatDefault;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -807,7 +815,7 @@ void cli_save(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mpw_free_string( &operation->sitesPath );
 | 
					    mpw_free_string( &operation->sitesPath );
 | 
				
			||||||
    operation->sitesPath = mpw_path( operation->file->user->fullName, extensions[0] );
 | 
					    operation->sitesPath = mpw_path( operation->user->fullName, extensions[0] );
 | 
				
			||||||
    dbg( "Updating: %s (%s)", operation->sitesPath, mpw_format_name( operation->sitesFormat ) );
 | 
					    dbg( "Updating: %s (%s)", operation->sitesPath, mpw_format_name( operation->sitesFormat ) );
 | 
				
			||||||
    mpw_free( &extensions, count * sizeof( *extensions ) );
 | 
					    mpw_free( &extensions, count * sizeof( *extensions ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -817,10 +825,9 @@ void cli_save(Arguments *args, Operation *operation) {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MPMarshalError marshalError = { .type = MPMarshalSuccess };
 | 
					    const char *buf = mpw_marshal_write( operation->sitesFormat, operation->file, operation->user );
 | 
				
			||||||
    const char *buf = mpw_marshal_write( operation->sitesFormat, operation->file, &marshalError );
 | 
					    if (!buf || operation->file->error.type != MPMarshalSuccess)
 | 
				
			||||||
    if (!buf || marshalError.type != MPMarshalSuccess)
 | 
					        wrn( "Couldn't encode updated configuration file:\n  %s: %s", operation->sitesPath, operation->file->error.message );
 | 
				
			||||||
        wrn( "Couldn't encode updated configuration file:\n  %s: %s", operation->sitesPath, marshalError.message );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if (fwrite( buf, sizeof( char ), strlen( buf ), sitesFile ) != strlen( buf ))
 | 
					    else if (fwrite( buf, sizeof( char ), strlen( buf ), sitesFile ) != strlen( buf ))
 | 
				
			||||||
        wrn( "Error while writing updated configuration file:\n  %s: %d", operation->sitesPath, ferror( sitesFile ) );
 | 
					        wrn( "Error while writing updated configuration file:\n  %s: %d", operation->sitesPath, ferror( sitesFile ) );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,7 +254,7 @@ const char *mpw_identicon_encode(
 | 
				
			|||||||
        const MPIdenticon identicon) {
 | 
					        const MPIdenticon identicon) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (identicon.color == MPIdenticonColorUnset)
 | 
					    if (identicon.color == MPIdenticonColorUnset)
 | 
				
			||||||
        return "";
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return mpw_str( "%hhu:%s%s%s%s",
 | 
					    return mpw_str( "%hhu:%s%s%s%s",
 | 
				
			||||||
            identicon.color, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory );
 | 
					            identicon.color, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@ const char *mpw_site_state(
 | 
				
			|||||||
/** @return An identicon (static) that represents the user's identity. */
 | 
					/** @return An identicon (static) that represents the user's identity. */
 | 
				
			||||||
const MPIdenticon mpw_identicon(
 | 
					const MPIdenticon mpw_identicon(
 | 
				
			||||||
        const char *fullName, const char *masterPassword);
 | 
					        const char *fullName, const char *masterPassword);
 | 
				
			||||||
/** @return An encoded representation (shared) of the given identicon or an empty string if the identicon is unset. */
 | 
					/** @return An encoded representation (shared) of the given identicon or NULL if the identicon is unset. */
 | 
				
			||||||
const char *mpw_identicon_encode(
 | 
					const char *mpw_identicon_encode(
 | 
				
			||||||
        const MPIdenticon identicon);
 | 
					        const MPIdenticon identicon);
 | 
				
			||||||
/** @return An identicon (static) decoded from the given encoded identicon representation or an identicon with empty fields if the identicon could not be parsed. */
 | 
					/** @return An identicon (static) decoded from the given encoded identicon representation or an identicon with empty fields if the identicon could not be parsed. */
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -28,6 +28,9 @@ MP_LIBS_END
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//// Types.
 | 
					//// Types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define mpw_default( __default, __value ) ({ __typeof__ (__default) _v = (__typeof__ (__default))(__value); _v = _v? _v: __default; })
 | 
				
			||||||
 | 
					#define mpw_default_n( __default, __num ) ({ __typeof__ (__default) _n = (__typeof__ (__default))(__num); _n = !isnan( _n )? _n: __default; })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef mpw_enum( unsigned int, MPMarshalFormat ) {
 | 
					typedef mpw_enum( unsigned int, MPMarshalFormat ) {
 | 
				
			||||||
    /** Do not marshal. */
 | 
					    /** Do not marshal. */
 | 
				
			||||||
            MPMarshalFormatNone,
 | 
					            MPMarshalFormatNone,
 | 
				
			||||||
@@ -122,12 +125,12 @@ typedef struct MPMarshalledSite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct MPMarshalledUser {
 | 
					typedef struct MPMarshalledUser {
 | 
				
			||||||
    MPMasterKeyProvider masterKeyProvider;
 | 
					    MPMasterKeyProvider masterKeyProvider;
 | 
				
			||||||
    MPAlgorithmVersion algorithm;
 | 
					 | 
				
			||||||
    bool redacted;
 | 
					    bool redacted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned int avatar;
 | 
					    unsigned int avatar;
 | 
				
			||||||
    const char *fullName;
 | 
					    const char *fullName;
 | 
				
			||||||
    MPIdenticon identicon;
 | 
					    MPIdenticon identicon;
 | 
				
			||||||
 | 
					    MPAlgorithmVersion algorithm;
 | 
				
			||||||
    const char *keyID;
 | 
					    const char *keyID;
 | 
				
			||||||
    MPResultType defaultType;
 | 
					    MPResultType defaultType;
 | 
				
			||||||
    time_t lastUsed;
 | 
					    time_t lastUsed;
 | 
				
			||||||
@@ -138,24 +141,24 @@ typedef struct MPMarshalledUser {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct MPMarshalledFile {
 | 
					typedef struct MPMarshalledFile {
 | 
				
			||||||
    MPMarshalledInfo *info;
 | 
					    MPMarshalledInfo *info;
 | 
				
			||||||
    MPMarshalledUser *user;
 | 
					 | 
				
			||||||
    MPMarshalledData *data;
 | 
					    MPMarshalledData *data;
 | 
				
			||||||
 | 
					    MPMarshalError error;
 | 
				
			||||||
} MPMarshalledFile;
 | 
					} MPMarshalledFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//// Marshalling.
 | 
					//// Marshalling.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Write the user and all associated data out using the given marshalling format.
 | 
					/** Write the user and all associated data out using the given marshalling format.
 | 
				
			||||||
 * @return A string (allocated), or NULL if the format is unrecognized, does not support marshalling or a format error occurred. */
 | 
					 * @return A string (allocated), or NULL if the file is missing, format is unrecognized, does not support marshalling or a format error occurred. */
 | 
				
			||||||
const char *mpw_marshal_write(
 | 
					const char *mpw_marshal_write(
 | 
				
			||||||
        const MPMarshalFormat outFormat, MPMarshalledFile *file, MPMarshalError *error);
 | 
					        const MPMarshalFormat outFormat, MPMarshalledFile *file, MPMarshalledUser *user);
 | 
				
			||||||
/** Best effort parse of metadata on the sites in the input buffer.  Fields that could not be parsed remain at their type's initial value.
 | 
					/** Parse the user configuration in the input buffer.  Fields that could not be parsed remain at their type's initial value.
 | 
				
			||||||
 * @return A metadata object (allocated); NULL if the object could not be allocated or the format was not understood. */
 | 
					 * @return The updated file object or a new one (allocated) if none was provided; NULL if a file object could not be allocated. */
 | 
				
			||||||
MPMarshalledInfo *mpw_marshal_read_info(
 | 
					 | 
				
			||||||
        const char *in);
 | 
					 | 
				
			||||||
/** Unmarshall sites in the given input buffer by parsing it using the given marshalling format.
 | 
					 | 
				
			||||||
 * @return A user object (allocated), or NULL if the format provides no marshalling or a format error occurred. */
 | 
					 | 
				
			||||||
MPMarshalledFile *mpw_marshal_read(
 | 
					MPMarshalledFile *mpw_marshal_read(
 | 
				
			||||||
        const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error);
 | 
					        MPMarshalledFile *file, const char *in);
 | 
				
			||||||
 | 
					/** Authenticate as the user identified by the given marshalled file.
 | 
				
			||||||
 | 
					 * @return A user object (allocated), or NULL if the file format provides no marshalling or a format error occurred. */
 | 
				
			||||||
 | 
					MPMarshalledUser *mpw_marshal_auth(
 | 
				
			||||||
 | 
					        MPMarshalledFile *file, const MPMasterKeyProvider masterKeyProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//// Creating.
 | 
					//// Creating.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,7 +178,7 @@ MPMarshalledQuestion *mpw_marshal_question(
 | 
				
			|||||||
/** Create or update a marshal file descriptor.
 | 
					/** Create or update a marshal file descriptor.
 | 
				
			||||||
 * @return The given file or new (allocated) if file is NULL; or NULL if the user is missing or the file couldn't be allocated. */
 | 
					 * @return The given file or new (allocated) if file is NULL; or NULL if the user is missing or the file couldn't be allocated. */
 | 
				
			||||||
MPMarshalledFile *mpw_marshal_file(
 | 
					MPMarshalledFile *mpw_marshal_file(
 | 
				
			||||||
        MPMarshalledFile *const file, MPMarshalledUser *user, MPMarshalledData *data, MPMarshalledInfo *info);
 | 
					        MPMarshalledFile *file, MPMarshalledInfo *info, MPMarshalledData *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//// Disposing.
 | 
					//// Disposing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -241,7 +244,7 @@ bool mpw_marshal_data_set_num(
 | 
				
			|||||||
bool mpw_marshal_data_vset_num(
 | 
					bool mpw_marshal_data_vset_num(
 | 
				
			||||||
        const double value, MPMarshalledData *data, va_list nodes);
 | 
					        const double value, MPMarshalledData *data, va_list nodes);
 | 
				
			||||||
/** Look up the string value at the given path in the data store.
 | 
					/** Look up the string value at the given path in the data store.
 | 
				
			||||||
 * @return The string value (allocated) or string representation of the number at this path; NULL if there is no such value at this path. */
 | 
					 * @return The string value (shared) or string representation of the number at this path; NULL if there is no such value at this path. */
 | 
				
			||||||
const char *mpw_marshal_data_get_str(
 | 
					const char *mpw_marshal_data_get_str(
 | 
				
			||||||
        const MPMarshalledData *data, ...);
 | 
					        const MPMarshalledData *data, ...);
 | 
				
			||||||
const char *mpw_marshal_data_vget_str(
 | 
					const char *mpw_marshal_data_vget_str(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user