JSON API » Sample clients » C

/*
This is a sample client for the Enswitch JSON API.
It is released into the public domain.
It comes with absolutely no warranty, and is not supported.

Compile with: gcc `pkg-config --cflags libcurl` `pkg-config --cflags json` sample.c `pkg-config --libs libcurl` `pkg-config --libs json` -o sample
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <json/json.h>

#define BASE "http://enswitch.example.com/api/json/"
#define FUNCTION "access/list"
#define USERNAME "testuser"
#define PASSWORD "testpass"

#define URL_SZ 256
#define BUF_SZ 10*1024

long written = 0;

void parse_json( json_object* j );

static int receive( void* buffer, size_t length, size_t size, void* data ) {
    size_t l = length * size;

    if ( l > 0 ) {
        if ( written + l >= BUF_SZ ) {
            fprintf( stderr, "Buffer size exceeded.\n" );
            return 0;
        }
        memcpy( &( (char*) data )[ written ], buffer, l );
        written += l;
    }

    return l;
}

void print_json( json_object* j ) {
    enum json_type type;

    type = json_object_get_type( j );
    switch ( type ) {
        case json_type_boolean: printf( "%s", json_object_get_boolean( j ) ? "true" : "false" );
            break;
        case json_type_double: printf( "%f", json_object_get_double( j ) );
            break;
        case json_type_int: printf( "%d", json_object_get_int( j ) );
            break;
        case json_type_string: printf( "%s", json_object_get_string( j ) );
            break;
    }
}

void parse_json_array( json_object* j, char* key ) {
    enum json_type type;

    json_object* a = j;
    if ( key ) {
        a = json_object_object_get( j, key );
    }

    int l = json_object_array_length( a );
    int i;
    json_object* v;
    for ( i = 0; i < l; i++ ) {
        v = json_object_array_get_idx( a, i );
        type = json_object_get_type( v );
        if ( type == json_type_array ) {
            parse_json_array( v, NULL );
        } else if ( type != json_type_object ) {
            printf( "value[ %d ]: ", i );
            print_json( v );
        } else {
            parse_json( v );
        }
    }
}

void parse_json( json_object* j ) {
    enum json_type type;

    json_object_object_foreach( j, key, v ) {
        type = json_object_get_type( v );
        switch ( type ) {
            case json_type_boolean:
            case json_type_double:
            case json_type_int:
            case json_type_string:
                if ( strcmp( key, "id" ) == 0 ) {
                    printf( "Remote access account %s=", key );
                    print_json( v );
                } else if ( strcmp( key, "name" ) == 0 ) {
                    printf( ", %s=", key );
                    print_json( v );
                    printf( "\n" );
                } else {
                    continue;
                }
                break;

            case json_type_object:
                j = json_object_object_get( j, key );
                parse_json( j );
                break;

            case json_type_array:
                if ( strcmp( key, "data" ) != 0 ) {
                    continue;
                }
                parse_json_array( j, key );
                break;
        }
    }
}

int main( int argc, char** argv ) {
	int r = -1;
    char url[ URL_SZ ];
    char data[ BUF_SZ ];

    memset( url, 0, sizeof( url ) );
    memset( data, 0, BUF_SZ );
	written = 0;

    sprintf( url, "%s%s?auth_username=%s;auth_password=%s", BASE, FUNCTION, USERNAME, PASSWORD );

	CURL* c = curl_easy_init();
	if ( ! c ) {
		return 1;
	}

	curl_easy_setopt( c, CURLOPT_URL, url );
	curl_easy_setopt( c, CURLOPT_WRITEFUNCTION, receive );
	curl_easy_setopt( c, CURLOPT_NOPROGRESS, 1 );
	curl_easy_setopt( c, CURLOPT_FAILONERROR, 1 );
	curl_easy_setopt( c, CURLOPT_WRITEDATA, data );
	curl_easy_setopt( c, CURLOPT_FOLLOWLOCATION, 1 );
	curl_easy_setopt( c, CURLOPT_TIMEOUT, 10 );

	r = curl_easy_perform( c );
	curl_easy_cleanup( c );
    if ( r != 0 ) {
        fprintf( stderr, "Curl Error: %d\n", r );
        return r;
    }

    json_object* j = json_tokener_parse( data );
    parse_json( j );

    return r;
}