/***************************************************************
 *
 * dvd_client_wrapper.c - Client Side DVD to RPC wrappers
 *
 * 
 * Demonstration code from 'Professional Linux Programming'
 * 
 * Written by Neil Matthew, Rick Stones et. al.
 * 
 * Copyright (C) 2000 Wrox Press.
 * 
 * http://www.wrox.com
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 **************************************************************/

#include <stdio.h>        /* fprintf() */
#include <stdlib.h>       /* for exit() */
#include <rpc/rpc.h>      /* always required for RPC */

/*
 * because some of the #defines and structure typedefs are in both
 * dvd.h and the automatically rpcgen-generated dvd_store.h, it is 
 * important to ensure that the dvd_store.h is included AFTER
 * the dvd.h
 */
#include "dvd.h"
#include "dvd_store.h"    /* dvd_store.h will be generated by rpcgen */

char* server_host_name = "localhost";
 
static CLIENT *_client = 0;

static void _dvd_rpc_client_init(void);
static void _dvd_rpc_client_shutdown(void);

int dvd_open_db(void)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta nie istnieje, to sprobuj go utworzyc
         */
        _dvd_rpc_client_init();
    }

    result = dvd_open_db_1((void *)0, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }
    return (status);
}

int dvd_open_db_login(const char *user, const char *password)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta nie istnieje, to sprobuj go utworzyc
         */
        _dvd_rpc_client_init();
    }

    result = dvd_open_db_1((void *)0, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }
    return (status);
}

int dvd_close_db(void)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 != _client) {
        result = dvd_close_db_1((void *)0, _client);
        _dvd_rpc_client_shutdown();
    }
    else {
        /*
         * wyglada na to, ze cos nas uprzedzilo w zerwaniu
         * polaczenia RPC... Czy dvd_close_db zostal wywolany
         * przed dvd_open_db lub dvd_open_db_login?
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_close_db(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif

        status = DVD_ERR_BAD_DATABASE;
    }

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }
    return (status);
}

int dvd_member_set(const dvd_store_member *member_record_to_update)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_set(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_member_set_1((dvd_store_member*)member_record_to_update, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }
    return (status);
}

int dvd_member_get(const int member_id, dvd_store_member *member_record_to_complete)
{
    dvd_member_get_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_get(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_member_get_1((int *)&member_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *member_record_to_complete = result->completed_member_record;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_member_create(dvd_store_member *member_record_to_add, int *member_id)
{
    dvd_member_create_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta jest zero, tzn. funkcja ta zostala
         * wywolana przed dvd_open_db albo dvd_open_db_login, to ustaw
         * znacznik dla wskazania bledu i zakoncz
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_create(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_member_create_1(member_record_to_add, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *member_record_to_add = result->updated_member_record;
            *member_id = result->member_id;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_member_delete(const int member_id)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta jest zero, tzn. funkcja ta zostala
         * wywolana przed dvd_open_db albo dvd_open_db_login, to ustaw
         * znacznik dla wskazania bledu i zakoncz
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_delete(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_member_delete_1((int*)&member_id, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_member_search(const char *lname, int **result_ids, int *count)
{
    dvd_member_search_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_search(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

   
    result = dvd_member_search_1((char **)&lname, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *result_ids = (result->result_ids).int_array_val;
            *count = result->count;
        }

        status =  (result->status);
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_member_get_id_from_number(const char *member_no, int *member_id)
{
    dvd_member_get_id_from_number_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_member_get_id_from_number(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_member_get_id_from_number_1((char **)&member_no, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *member_id = result->member_id;
        }

        status =  result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_title_set(const dvd_title *title_record_to_update)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_set(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_title_set_1((dvd_title*)title_record_to_update, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_title_get(const int title_id, dvd_title *title_record_to_complete)
{
    dvd_title_get_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_get(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_title_get_1((int *)&title_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *title_record_to_complete = result->completed_title_record;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);

}

int dvd_title_create(dvd_title *title_record_to_add, int *title_id)
{
    dvd_title_create_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_create(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_title_create_1(title_record_to_add, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *title_record_to_add = result->updated_title_record;
            *title_id = result->title_id;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_title_delete(const int title_id)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_delete(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_title_delete_1((int *)&title_id, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_title_search(const char *title, const char *name, int *result_ids[], int *count)
{
    dvd_title_search_res *result;
    dvd_title_search_arg title_search_arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_search(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    title_search_arg.title = (char *)title;
    title_search_arg.name = (char *)name;

    result = dvd_title_search_1((dvd_title_search_arg *)&title_search_arg, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *result_ids = (result->result_ids).int_array_val;
            *count = result->count;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_set(const dvd_disk *disk_record_to_update)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_set(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_set_1((dvd_disk *)disk_record_to_update, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_get(const int disk_id, dvd_disk *disk_record_to_complete)
{
    dvd_disk_get_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_get(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_get_1((int *)&disk_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *disk_record_to_complete = result->completed_disk_record;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_create(dvd_disk *disk_record_to_add, int *disk_id)
{
    dvd_disk_create_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_create(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_create_1(disk_record_to_add, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            /* structure copy */
            *disk_record_to_add = result->updated_disk_record;
            *disk_id = result->disk_id;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_delete(const int disk_id)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_delete(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_delete_1((int *)&disk_id, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_search(const int title_id, int *result_ids[], int *count)
{
    dvd_disk_search_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta jest zero, tzn funkcja ta zostala
         * wywolana przed dvd_open_db albo dvd_open_db_login, to ustaw
         * znacznik dla wskazania bledu i zakoncz
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_search(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_search_1((int *)&title_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *result_ids = (result->result_ids).int_array_val;
            *count = result->count;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_get_genre_list(char **genre_list[], int *count)
{
    dvd_get_genre_list_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * jesli uchwyt klienta jest zero, tzn. funkcja ta zostala
         * wywolana przed dvd_open_db albo dvd_open_db_login, to ustaw
         * znacznik dla wskazania bledu i zakoncz
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_get_genre_list(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_get_genre_list_1((void *)0, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *genre_list = (result->genre_list).genre_list_val;
            *count = (result->count);
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}
 
int dvd_get_classification_list(char **class_list[], int *count)
{
    dvd_get_classification_list_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_get_classification_list(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_get_classification_list_1((void *)0, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *class_list = (result->class_list).class_list_val;
            *count = (result->count);
        }
    
        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_err_text(const int err_number, char **message_to_show)
{
    dvd_err_text_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_err_text(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
    }

    result = dvd_err_text_1((int *)&err_number, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *message_to_show = result->message_to_show;
        }
    
        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_today(char **date)
{
    dvd_today_res *result;
    int status = DVD_ERR_BAD_DATABASE;
    int _is_temp_rpc_connection = 0;

    /*
     * dvd_today doesn't rely on dvd_open_db being called beforehand
     * it will create a temporary connection to the RPC server if one
     * does not already exist, and release it afterwards
     */
    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_today(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
        fprintf(stderr, "RPC_CLIENT - dvd_today(): making temporary RPC connection\n");
#endif

        _dvd_rpc_client_init();

        _is_temp_rpc_connection = 1;

    }
 
    result = dvd_today_1((void *)0, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *date = result->date;
        }
    
        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    if (0 != _is_temp_rpc_connection) {
        _dvd_rpc_client_shutdown();
    }

    return (status);
}
 
int dvd_rent_title(const int member_id, const int title_id, int *disk_id)
{
    dvd_rent_title_res *result;
    dvd_rent_title_arg rent_title_arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_rent_title(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    rent_title_arg.member_id = member_id;
    rent_title_arg.title_id = title_id;

    result = dvd_rent_title_1(&rent_title_arg, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *disk_id = result->disk_id;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_rented_disk_info(const int disk_id, int *member_id, char *date_rented)
{
    dvd_rented_disk_info_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_rented_disk_info(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_rented_disk_info_1((int *)&disk_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *member_id = result->member_id;
            strcpy(date_rented, result->date_rented);
        }
 
        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_disk_return(const int disk_id, int *member_id, char *date)
{
    dvd_disk_return_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_disk_return(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_disk_return_1((int *)&disk_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *member_id = result->member_id;
            strcpy(date, result->date);
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_overdue_disks(const char *date1, const char *date2, int *disk_ids[], int *count)
{
    dvd_overdue_disks_res *result;
    dvd_overdue_disks_arg overdue_disks_arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_overdue_disks(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    /*
     * cast away the 'const' here to stop compiler complaining
     */
    overdue_disks_arg.date1 = (char *)date1;
    overdue_disks_arg.date2 = (char *)date2;

    result = dvd_overdue_disks_1(&overdue_disks_arg, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *count = result->count;
            *disk_ids = (result->disk_ids).int_array_val;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_title_available(const int title_id, const char *date, int *count)
{
    dvd_title_available_res *result;
    dvd_title_available_arg title_available_arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_title_available(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    title_available_arg.title_id = title_id;
    title_available_arg.date = (char *)date;
    result = dvd_title_available_1(&title_available_arg, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *count = result->count;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_reserve_title(const char *date, const int title_id, const int member_id)
{
    int *result;
    dvd_reserve_title_arg reserve_title_arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_reserve_title(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    /*
     * cast away the 'const' here to stop compiler complaining
     */
    reserve_title_arg.date = (char *)date;
    reserve_title_arg.title_id = (int)title_id;
    reserve_title_arg.member_id = (int)member_id;

    result = dvd_reserve_title_1(&reserve_title_arg, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_reserve_title_cancel(const int member_id)
{
    int *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_reserve_title_cancel(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_reserve_title_cancel_1((int *)&member_id, _client);

    if (NULL != result) {
        status = *result;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_reserve_title_query_by_member(const int member_id, int *title_id)
{
    dvd_reserve_title_query_by_member_res *result;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_reserve_title_query_by_member(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    result = dvd_reserve_title_query_by_member_1((int *)&member_id, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *title_id = result->title_id;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}

int dvd_reserve_title_query_by_titledate(const int title_id, const char *date, int *member_ids[], int *count)
{
    dvd_reserve_title_query_by_titledate_res *result;
    dvd_reserve_title_query_by_titledate_arg arg;
    int status = DVD_ERR_BAD_DATABASE;

    if (0 == _client) {
        /*
         * if the client handle is zero, i.e this function has been called
         * before either dvd_open_db or dvd_open_db_login, then flag this
         * as an error and die
         */
#ifdef RPC_DEBUG
        fprintf(stderr, "RPC_CLIENT - dvd_reserve_title_query_by_titledate(): handle is null at %s:%d\n", 
            __FILE__, __LINE__);
#endif
        exit(1);
    }

    arg.title_id = title_id;
    arg.date = (char *)date;

    result = dvd_reserve_title_query_by_titledate_1(&arg, _client);

    if (NULL != result) {
        if (DVD_SUCCESS == result->status) {
            *member_ids = (result->member_ids).int_array_val;
            *count = result->count;
        }

        status = result->status;
    } else {
        clnt_pcreateerror(server_host_name);
    }

    return (status);
}


/*
 * trzeba sie upewnic, ze kiedy dvd_open_db lub dvd_open_db_login
 * jest wywolana to polaczenie RPC do procesu serwera jest utworzone 
 */
static void _dvd_rpc_client_init(void) {
    _client = clnt_create(server_host_name, DVD_STORE_PROG, DVD_STORE_VERS, "tcp");

    if (NULL == _client) {
        /*
         * nie mozna nawiazac polaczenia z serwerem, tak wiec
         * drukuj komunikat o bledzie i koncz 
         */
        clnt_pcreateerror(server_host_name);
        exit(1);
    }
}

/*
 * zerwij polaczenie RPC, kiedy dvd_close_db jest wywolana 
 */
static void _dvd_rpc_client_shutdown(void) {
    if (0 != _client) {
        clnt_destroy(_client);
        _client = 0;
    }
}
