示例#1
0
文件: main.c 项目: MattMarji/storage
END_TEST

START_TEST (test_conninvalid_disconnectinvalidparam)
{
	int status = storage_disconnect(NULL);
	fail_unless(status == -1, "storage_disconnect with invalid param should fail.");
	fail_unless(errno == ERR_INVALID_PARAM, "storage_disconnect with invalid param not setting errno properly.");
}
示例#2
0
void libetpan_storage_disconnect(struct mailengine * engine,
                                 struct mailstorage * storage)
{
    struct storage_ref_info * ref_info;

    ref_info = get_storage_ref_info(engine, storage);

    storage_disconnect(ref_info);
}
示例#3
0
/**
 * @brief Attempts to disconnect from the server.
 * @return Returns 0 on success, -1 otherwise.
 */
int client_disconnect()
{
    int status = storage_disconnect(conn);
    
    if(status != 0)
        printf("storage_disconnect failed. Error code: %d.\n", errno);
    else
    {
        printf("Server connection closed.\n");
        conn = NULL;
    }
    
    return status;
}
示例#4
0
END_TEST


START_TEST (test_conn_basic)
{
	int serverpid = start_server(ONETABLE_CONF, NULL, "test_conn_basic.serverout");
	fail_unless(serverpid > 0, "Server didn't run properly.");

	void *conn = storage_connect(SERVERHOST, server_port);
	fail_unless(conn != NULL, "Couldn't connect to server.");

	int status = storage_disconnect(conn);
	fail_unless(status == 0, "Error disconnecting from the server.");
}
示例#5
0
/**
 * @brief Attempts to authenticate the user with the server.
 *
 * Closes server connection and exits if the user fails to authenticate.
 * @return Returns 0 on success, -1 otherwise.
 */
int client_auth()
{
    
    char username[MAX_USERNAME_LEN] = {0}, password[MAX_ENC_PASSWORD_LEN] = {0};
    
    bool read_success = false;
    while(read_success == false)
    {
        printf("Please enter the username: "******"%s %s", username, trash) != 1))
            printf("Please enter a valid username (no spaces).\n");
        else
            read_success = true;
    }
    
    read_success = false;
    while(read_success == false)
    {
        printf("Please enter the password: "******"%s %s", password, trash) != 1))
            printf("Please enter a valid password (no spaces).\n");
        else
            read_success = true;
    }
    
    int i;
    char pass_asterik[strlen(password) + 1];
    for(i = 0; i < strlen(password); i++)
        pass_asterik[i] = '*';
    pass_asterik[i] = 0;
    
    int status = storage_auth(username, password, conn);
    if(status != 0)
    {
        printf("storage_auth failed with username '%s' and password '%s'. " \
               "Error code: %d.\n", username, pass_asterik, errno);
        storage_disconnect(conn);
    }
    else
        printf("storage_auth: successful.\nWelcome %s!\n", username);
    
    return status;
}
示例#6
0
END_TEST


/*
 * Connection tests:
 * 	connect to and disconnect from server (pass)
 * 	connect to server without server running (fail)
 * 	connect to server with invalid hostname (fail)
 * 	disconnect from server with invalid params (fail)
 */

START_TEST (test_conn_basic)
{
	int serverpid = start_server(ONETABLE_CONF, NULL, "test_conn_basic.serverout");
	fail_unless(serverpid > 0, "Server didn't run properly.");

	void *conn = storage_connect(SERVERHOST, server_port);
	fail_unless(conn != NULL, "Couldn't connect to server.");

	int status = storage_disconnect(conn);
	fail_unless(status == 0, "Error disconnecting from the server.");
}
示例#7
0
/**
 * @brief Text fixture teardown.  Disconnect from the server.
 */
void test_teardown()
{
	// Disconnect from the server.
	storage_disconnect(test_conn);
	//fail_unless(status == 0, "Error disconnecting from the server.");
}
示例#8
0
int main(int argc, char *argv[])
{
	// initial variables used throughout all of the commands
	int i;
	int SERVERPORT;
	char SERVERHOST[MAX_HOST_LEN], SERVERUSERNAME[MAX_USERNAME_LEN], SERVERPASSWORD[MAX_ENC_PASSWORD_LEN], SERVERPORTstr[MAX_PORT_LEN];
	char TABLE[MAX_TABLE_LEN], KEY[MAX_KEY_LEN];
	char **key = malloc(sizeof(char**)*800);
	char PREDICATES_1[500];
	char PREDICATES[500];
	void *conn = NULL;
	int status;
	struct storage_record r;
	int authenticated = 0;

	do{
		printmenu(&i); // function to prompt the user for the menu and read in and update the variable i

		if(i == 0){// Connect to server
			if(conn != NULL)
				printf("You are already connected. Please choose another option.\n\n");
			else
			{
				conn = storage_connect("localhost",2222);
				if(!conn)
				{
					printf("Cannot connect to server @ %s:%d. Error code: %d.\n", SERVERHOST, SERVERPORT, errno);
					//return -1;
				}
				else printf("\nUser conncected with the server\n");
				status = storage_auth("admin", "dog4sale", conn);
				if(status != 0)
				{
					printf("storage_auth failed with username '%s' and password '%s'. " \
					"Error code: %d, status: %d\n", SERVERUSERNAME, SERVERPASSWORD, errno, status);
					//storage_disconnect(conn);
					//return status;
				}
				else{
					authenticated = 1;
					printf("\nUser authenticated with the server\n");
				}
			}
		}
		if(i == 1)
		{// Connect to server
			if(conn != NULL)
				printf("You are already connected. Please choose another option.\n\n");
			else
			{
				printf("Enter the Server Host\n");
				fgets(SERVERHOST, MAX_HOST_LEN, stdin);
				sscanf(SERVERHOST, "%s", SERVERHOST);
				printf("Enter the Server Port\n");
				fgets(SERVERPORTstr, MAX_PORT_LEN, stdin);
				sscanf(SERVERPORTstr, "%d", &SERVERPORT);
				conn = storage_connect(SERVERHOST, SERVERPORT);
				if(!conn)
				{
					printf("Cannot connect to server @ %s:%d. Error code: %d.\n", SERVERHOST, SERVERPORT, errno);
					//return -1;
				}
				else printf("\nUser connected with the server\n");
			}
		}

		else if(i == 2)
		{// Authenticate the client.
			if(conn == NULL)
				printf("You are not connected yet. Please connect to the server first.\n\n");
			//else if(authenticated == 1)
				//printf("You are already authenticated. Please choose another option.\n\n");
			else
			{
				printf("Enter the UserName Host\n");
				fgets(SERVERUSERNAME, MAX_USERNAME_LEN, stdin);
				sscanf(SERVERUSERNAME, "%s", SERVERUSERNAME);
				printf("Enter the Password Host\n");
				fgets(SERVERPASSWORD, MAX_ENC_PASSWORD_LEN, stdin);
				sscanf(SERVERPASSWORD, "%s", SERVERPASSWORD);
				status = storage_auth(SERVERUSERNAME, SERVERPASSWORD, conn);
				if(status != 0)
				{
					printf("storage_auth failed with username '%s' and password '%s'. " \
							"Error code: %d, status: %d\n", SERVERUSERNAME, SERVERPASSWORD, errno, status);
				}
				else{
					authenticated = 1;
					printf("\nUser authenticated with the server\n");
				}
			}
		}

		else if(i == 3)
		{// SET command
			if(conn == NULL)
				printf("You are not connected yet. Please connect to the server first.\n\n");
			else
			{
				printf("Please enter the Table\n");
				fgets(TABLE, MAX_TABLE_LEN, stdin);
				sscanf(TABLE, "%s", TABLE);
				printf("Please enter the Key\n");
				fgets(KEY, MAX_KEY_LEN, stdin);
				sscanf(KEY, "%s", KEY);
				printf("Please Enter the record that you wish to store\n");
				fgets(r.value, MAX_VALUE_LEN, stdin);
				r.value[strlen(r.value)-1] = '\0';
				//strncpy(r.value, value, sizeof value);

				//This is for measuring the server processing time
				//remember when the process started
				clock_t t;
				t=clock();
				//issue set call to DATABASE with TABLE, KEY and r.value
				if(!strcmp(r.value,"null")){
					status = storage_set(TABLE,KEY,NULL,conn);
				}
				if(strcmp(r.value,"null"))
				status = storage_set(TABLE, KEY, &r, conn);
				//find how long it took to perform the GET operation
				//current time minus the time when the operation started
				t=clock()-t;

				if(status != 0)
				{
					printf("storage_set failed. Error code: %d.\n", errno);
				}
				else
					printf("storage_set: successful.\n");
			}
		}

		else if(i == 4)
		{// GET command
			if(conn == NULL)
				printf("You are not connected yet. Please connect to the server first.\n\n");
			//else if(authenticated == 0)
				//printf("You are not authenticated yet. Please authenticate first.\n\n");
			else
			{
				printf("Please enter the Table\n");
				fgets(TABLE, MAX_TABLE_LEN, stdin);
				sscanf(TABLE, "%s", TABLE);
				printf("Please enter the Key\n");
				fgets(KEY, MAX_KEY_LEN, stdin);
				sscanf(KEY, "%s", KEY);
				status = storage_get(TABLE, KEY, &r, conn);
				if(status != 0)
				{
					printf("storage_get failed. Error code: %d.\n", errno);
					storage_disconnect(conn);
					return status;
				}
				else
					printf("storage_get: the value returned for key '%s' is '%s'.\n", KEY, r.value);
			}
		}

		else if(i == 5)
		{// QUERY command
			if(conn == NULL)
				printf("You are not connected yet. Please connect to the server first.\n\n");
			else
			{
				printf("Please enter the Table\n");
				fgets(TABLE, MAX_TABLE_LEN, stdin);
				sscanf(TABLE, "%s", TABLE);

				printf("Please enter the Predicates\n");
				fgets(PREDICATES_1, 500, stdin);
				sscanf(PREDICATES_1, "%[^'\n]",PREDICATES);
				// (const char *table, const char *predicates, char **keys, const int max_keys, void *conn)
				status = storage_query(TABLE, PREDICATES, key, &r, conn);
				//int foundkeys = storage_query(INTTABLE, "col<-1", test_keys, MAX_RECORDS_PER_TABLE, test_conn);
				printf("status/number of keys: %d\n",status);
				if(status == -1)
				{
					printf("storage_query failed. Error code: %d.\n", errno);
					storage_disconnect(conn);
					return status;
				}
				else {
					int p = 0;

					int i = 0;

					while (key[i] != NULL){
						printf("key: '%s'\n", key[i]);
						i++;

					}
				}
			}
		}


		else if(i==6)
		{// Disconnect from server
			status = storage_disconnect(conn);
			if(status != 0)
			{
				printf("storage_disconnect failed. Error code: %d.\n", errno);
				return status;
			}
			else
			{
				conn = NULL;
				authenticated = 0;
				printf("You are now disconnected\n");
			}
		}
		else if (i==8){
			// import the census into the data base
			if(conn == NULL)
				printf("You are not connected yet. Please connect to the server first.\n\n");
			 FILE* fp;
			fp=fopen("census", "r");               //open the file for reading only
   			if(fp == NULL)
   			 printf("Error opening file");
  			 else
   			{
				int loop;
       				//populate the table with all the data in the data file (city + its population)
				do {
					char name[100];
					char value[MAX_VALUE_LEN];
					char line[100];
       					char *l = fgets(line, sizeof line, fp);
					if (!feof(fp)){
						sscanf(l, "%s %s", name, value);
						printf("name: %s , value: %s \n", name, value);
						strcpy(r.value,value);
						status = storage_set("census", name, &r, conn);
						if(status != 0)
						{
							printf("storage_set failed. Error code: %d.\n", errno);
						}			
					}
					
				   }
       				 while(!feof(fp));     //read the first line (city)	
   			}
		}

	} while (i!=7); // if i is 6, we want to exit from client

	// Exit
	return 0;
}
示例#9
0
const char* testClient(void* parameters)
{
    struct workerTask* worker = (struct workerTask*)parameters;
    
    uint16_t randContext[3];
    for(int i = 0; i < 3; i++)
    {
        randContext[i] = time(NULL) ^ worker->workerID;
    }
    
    if(!worker->conn)
    {
        //spread the load from new connections so the server won't be overloaded
        usleep(erand48(randContext) * 1000 + 1000*worker->connOpenDelay);
        
        worker->conn = storage_connect(worker->hostname, worker->port);
        if(!worker->conn)
        {
            printf("storage_connect failed\n");
            return ece297strerror(errno);
        }
        
        int result = storage_auth(worker->username, worker->password, worker->conn);
        if(result == -1)
        {
            printf("storage_auth failed\n");
            storage_disconnect(worker->conn);
            worker->conn = NULL;
            return ece297strerror(errno);
        }
    }
    
    uint64_t loopCount = worker->numKeys;
    if(worker->type == kClientRunWorkload)
    {
        loopCount = worker->count;
    }
    
    uint64_t period = 0;
    
    //0 throughput = no limit
    if(worker->throughput)
    {
        period = (1/worker->throughput) * 1000000;
        
        //start at a random time
        usleep(erand48(randContext) * period);
    }
    struct timeval next;
    gettimeofday(&next, NULL);
    
    for(uint64_t i = 0; i < loopCount; i++)
    {
        if(worker->throughput)
        {
            int64_t timeRemaining = -uSElapsed(&next);
            if(timeRemaining > 0)
            {
                usleep((uint32_t)timeRemaining);
            }
            uint64_t newTime = next.tv_usec + period;
            next.tv_sec += newTime / 1000000;
            next.tv_usec = newTime % 1000000;
        }
        switch (worker->type)
        {
            case kClientAddKeys:
            {
                char keyBuf[20]; //as per ECE297 spec
				stringGen(worker->startingKey + i, worker->keySecret, keyBuf, sizeof(keyBuf));
                
                struct storage_record record;
                memset(&record.metadata, 0, sizeof(record.metadata));
                
				stringGen(worker->startingKey + i, worker->valueSecret, record.value, sizeof(record.value));
                                				
                struct timeval start;
                gettimeofday(&start, NULL);
                if(storage_set(worker->table, keyBuf, &record, worker->conn) == -1)
                {
                    printf("storage_set failed\n");
                    return ece297strerror(errno);
                }
                recordLatency(timeElapsed(&start), worker->latencyResults);
                break;
            }
                                
            case kClientRunWorkload:
            {
				//WATCH the floating point promotion - it must be cast to a uint64_t BEFORE adding worker->startingKey
                uint64_t keyIndex = ((uint64_t)(erand48(randContext) * worker->numKeys)) + worker->startingKey;
                
                char keyBuf[20]; //as per ECE297 spec
				stringGen(keyIndex, worker->keySecret, keyBuf, sizeof(keyBuf));
                char expectedValue[1024];
				stringGen(keyIndex, worker->valueSecret, expectedValue, sizeof(expectedValue));
				
                struct timeval start;
                gettimeofday(&start, NULL);
                struct storage_record rec;
                if(storage_get(worker->table, keyBuf, &rec, worker->conn) == -1)
                {
                    printf("storage_get failed (key index = %u)\n", keyIndex);
                    return ece297strerror(errno);
                }
                if(strcmp(rec.value, expectedValue)) {
                	return "Server returned incorrect key";
                }
				
                recordLatency(timeElapsed(&start), worker->latencyResults);
            }
        }
    }
    return NULL;
}
示例#10
0
文件: slave.c 项目: rv1/esb
int beginSlavery(int fd)
{
    uint16_t randContext[3];
    for(int i = 0; i < 3; i++)
    {
        randContext[i] = time(NULL) ^ getpid();
    }
    
    int returnCode = -1;
    
    json_t* params = NULL;
    json_t* nextCommand = NULL;
    
    char** values = NULL;
    
    struct workerTask* tasks = NULL;
    
    uint32_t connPoolSize = 128;
    uint32_t connPoolCount = 0;
    void** connPool = __xmalloc(sizeof(void*) * connPoolSize);
    memset(connPool, 0, sizeof(void*) * connPoolSize);
    
    //recieve initial parameters
    params = readCommand(fd, 5000);
    if(!params)
    {
        fprintf(stderr, "No initialization packet\n");
        goto exit;
    }
    
    //make sure the initial packet has all of the required info
    uint64_t slaveID;
    const char* command;
    const char* address;
    const char* username;
    const char* password;
    const char* tableName;
    int port;
    int errorChecking;
    int valueLength;
    int result = json_unpack(params, "{s:s, s:s, s:i, s:I, s:s, s:s, s:s, s:b, s:i}",
                             "command",         &command,
                             "address",         &address,
                             "port",            &port,
                             "slave-id",        &slaveID,
                             "username",        &username,
                             "password",        &password,
                             "table",           &tableName,
                             "error-checking",  &errorChecking,
                             "value-length",    &valueLength);
    if(result != 0 || strcmp(command, "init") || port <= 0 || port > 65535)
    {
        fprintf(stderr, "Invalid initialization packet recieved\n");
        goto exit;
    }

    uint64_t numKeys = 0;
    
    //loop and execute commands from the master
    while(1)
    {
        nextCommand = readCommand(fd, 15000);
        if(!nextCommand)
        {
            fprintf(stderr, "Invalid next command\n");
            goto exit;
        }
                        
        const char* command;
        int result = json_unpack(nextCommand, "{s:s}", "command", &command);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing command field\n");
            goto exit;
        }
        
        //parse commands and modify keyRange array if needed
        struct workerTask task;
        
        if(!strcmp(command, "add"))
        {
            uint64_t numKeysToAdd;
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToAdd);
            if(result == -1)
            {
                goto exit;
            }

            if(errorChecking)
            {
                values = __xrealloc(values, sizeof(char*) * (numKeys + numKeysToAdd));
                for(uint64_t i = 0; i < numKeysToAdd; i++)
                {
                    values[numKeys + i] = __xmalloc(valueLength + 1);
                    for(int j = 0; j < valueLength; j++)
                    {
                        values[numKeys + i][j] = (erand48(randContext) * 26) + 'A';
                    }
                    values[numKeys + i][valueLength] = '\0';
                }
            }
            task.startingKey = slaveID + numKeys;
            task.numKeys = numKeysToAdd;
            task.type = kClientAddKeys;
            task.values = values;
            numKeys += task.numKeys;
        }
        else if(!strcmp(command, "remove"))
        {
            uint64_t numKeysToRemove;
            
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToRemove);
            if(result == -1)
            {
                goto exit;
            }
            
            if(errorChecking)
            {
                uint64_t position = numKeys - numKeysToRemove;
                for(uint64_t i = 0; i < numKeysToRemove; i++)
                {
                    free(values[position + i]);
                }
                values = __xrealloc(&values, sizeof(char*) * (numKeys - numKeysToRemove));
            }
            if(numKeysToRemove > numKeys)
            {
                goto exit;
            }
            task.startingKey = slaveID + numKeys - numKeysToRemove;
            task.numKeys = numKeysToRemove;
            task.type = kClientRemoveKeys;
            task.values = NULL;
            numKeys -= numKeysToRemove;
        }
        else if(!strcmp(command, "test"))
        {
            json_t* array = json_object_get(nextCommand, "workload");

            //right now we only need 1 workload type
            if(!(json_is_array(array) && json_array_size(array) == kWorkloadTypes))
            {
                goto exit;
            }
            for(int i = 0; i < kWorkloadTypes; i++)
            {
                task.workloadComposition[i] = json_number_value(json_array_get(array, i));
            }
            int result = json_unpack(nextCommand, "{s:I}", "amount", &task.count);
            if(result == -1)
            {
                goto exit;
            }
            task.startingKey = slaveID;
            task.numKeys = numKeys;
            task.values = values;
            task.type = kClientRunWorkload;
        }
        else if(!strcmp(command, "quit"))
        {
            returnCode = 0;
            goto exit;
        }
        else
        {
            fprintf(stderr, "unknown command from client: %s\n", command);
            goto exit;
        }
        
        int numClients;
        result = json_unpack(nextCommand, "{s:i, s:F}", "num-clients", &numClients, "throughput", &task.throughput);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing number of clients or throughput value\n");
            goto exit;
        }
                
        task.connOpenDelay = 0;
        
        //fill out the generic task information
        task.table = tableName;
        task.valueSize = valueLength;
        task.workerID = slaveID;
        task.hostname = address;
        task.username = username;
        task.password = password;
        task.port = port;
        
        //split the request between the clients
        while(numClients >= connPoolSize)
        {
            size_t oldSize = connPoolSize;
            connPoolSize *= 8;
            connPool = __xrealloc(connPool, connPoolSize * sizeof(void*));
            memset(&connPool[oldSize], 0, sizeof(void*) * oldSize * 7);
        }
        
        if(numClients < connPoolCount)
        {
            for(int i = connPoolCount - 1; i >= numClients; i--)
            {
                storage_disconnect(connPool[i]);
                connPool[i] = NULL;
            }
        }
        
        tasks = __xmalloc(sizeof(struct workerTask) * numClients);
        splitTasks(&task, tasks, numClients, connPool);
                
        //perform the request
        json_t* requestResponse;
        performRequest(tasks, numClients, &requestResponse);
        
        //save the connections for next time
        for(int i = 0; i < numClients; i++)
        {
            connPool[i] = tasks[i].conn;
        }
        connPoolCount = numClients;
        
        //send the result back to the master
        char* serialResponse = json_dumps(requestResponse, JSON_COMPACT);
        json_decref(requestResponse);
        size_t len = strlen(serialResponse);
        if(len > 1048576)
        {
            fprintf(stderr, "Response too large (%zd)\n", len);
            free(serialResponse);
            goto exit;
        }
        char sizeBuf[9];
        sprintf(sizeBuf, "%08d", (int)len);
        sendAll(fd, sizeBuf, 8);
        
        if(sendAll(fd, serialResponse, strlen(serialResponse)) == -1)
        {
            free(serialResponse);
            goto exit;
        }
        free(serialResponse);

        free(tasks);
        tasks = NULL;        
        
        //free the parsed command
        json_decref(nextCommand);
        nextCommand = NULL;
    }
    
exit:
    for(uint32_t i = 0; i < connPoolCount; i++)
    {
        storage_disconnect(connPool[i]);
    }
    free(connPool);
    free(tasks);
    json_decref(nextCommand);
    json_decref(params);
    if(values)
    {
        for(uint64_t i = 0; i < numKeys; i++)
        {
            free(values[i]);
        }
        free(values);
    }
    return returnCode;
}
示例#11
0
/**
 * @brief Start a client to interact with the storage server.
 *
 * If connect is successful, the client performs a storage_set/get() on
 * TABLE and KEY and outputs the results on stdout. Finally, it exists
 * after disconnecting from the server.
 */
int main(int argc, char *argv[])
{
    if(LOGGING == 1)
        ClientFile = stdout;
    else if(LOGGING == 2)
    {
        time_t Time = time(NULL);
        struct tm *currentTime = localtime(&Time);
        char ClientFileName[MAX_CONFIG_LINE_LEN];
        int day = currentTime->tm_mday;
        int month = currentTime->tm_mon + 1; // Month is 0 - 11, add 1 to get a jan-dec 1-12 concept
        int year = currentTime->tm_year + 1900;
        int hour = currentTime->tm_hour;
        int minute = currentTime->tm_min;
        int second = currentTime->tm_sec;
        snprintf(ClientFileName, sizeof ClientFileName, "Client-%d-%02d-%02d-%02d-%02d-%02d.log",year,month,day,hour,minute,second);//making a string
        ClientFile = fopen(ClientFileName,"a");
    }
        int selection = 0, port, status;
        char hostname[MAX_HOST_LEN+1], username[MAX_USERNAME_LEN], password[MAX_ENC_PASSWORD_LEN],table[MAX_TABLE_LEN],key[MAX_KEY_LEN], strc[MAX_CONFIG_LINE_LEN];
        struct storage_record r;
        void *conn;
    // Client Interaction with the server
    while(selection!=6)
    {
        printf("> ----------------------\n");
        printf("> 1) Connect\n");
        printf("> 2) Authenticate\n");
        printf("> 3) Get\n");
        printf("> 4) Set\n");
        printf("> 5) Disconnect\n");
        printf("> 6) Exit\n");
        printf("> ----------------------\n");
        printf("> Please enter your selection: ");
        scanf("%d",&selection);
        
        // Connect to server
        if(selection == 1)
        {
            printf("> Please input the hostname: ");
            scanf("%s",hostname);
            printf("> Please input the port: ");
            scanf("%d",&port);
            conn = storage_connect(hostname, port);
            if(!conn)
            {
                snprintf(strc, sizeof strc, "> Cannot connect to server @ %s:%d. Error code: %d.\n",hostname, port, errno);
                printf("%s",strc);
                logger(ClientFile,"a");
                return -1;
            }
            snprintf(strc, sizeof strc, "> Connecting to %s:%d ...\n",hostname,port);
            printf("%s",strc);
            logger(ClientFile,"a");
        }
        
        // Authenticate the client.
        else if (selection == 2)
        {
            printf("> Please enter your username: "******"%s",username);
            printf("> Please enter your password: "******"%s",password);
            status = storage_auth(username, password, conn);
            if(status != 0)
            {
                snprintf(strc, sizeof strc, "> storage_auth failed with username '%s' and password '%s'. " \
                       "Error code: %d.\n", username, password, errno);
                printf("%s",strc);
                logger(ClientFile,strc);
                storage_disconnect(conn);
                return status;
            }
            snprintf(strc, sizeof strc, "> storage_auth: successful.\n");
            printf("%s",strc);
            logger(ClientFile,strc);
        }
        
        // Issue storage_get
        else if (selection == 3)
        {
            printf("> Please enter table name: ");
            scanf("%s",table);
            printf("> Please enter key: ");
            scanf("%s",key);
            status = storage_get(table, key, &r, conn);
            if(status != 0)
            {
                snprintf(strc, sizeof strc, "> storage_get failed. Error code: %d.\n", errno);
                printf("%s",strc);
                logger(ClientFile,strc);
                storage_disconnect(conn);
                return status;
            }
            snprintf(strc, sizeof strc, "> storage_get: the value returned for key '%s' is '%s'.\n",
                   key, r.value);
            printf("%s",strc);
            logger(ClientFile,strc);
        }
        // Issue storage_set
        else if(selection == 4)
        {
            printf("> Please enter table name: ");
            scanf("%s",table);
            printf("> Please enter key: ");
            scanf("%s",key);
            
            strncpy(r.value, "some_value", sizeof r.value);
            status = storage_set(table, key, &r, conn);
            if(status != 0)
            {
                snprintf(strc, sizeof strc, "> storage_set failed. Error code: %d.\n", errno);
                printf("%s",strc);
                logger(ClientFile,strc);
                storage_disconnect(conn);
                return status;
            }
            snprintf(strc, sizeof strc, "> storage_set: successful.\n");
            printf("%s",strc);
            logger(ClientFile,strc);
        }
        // Disconnect from server
        else if (selection == 5)
        {
            status = storage_disconnect(conn);
            if(status != 0)
            {
                snprintf(strc, sizeof strc, "> storage_disconnect failed. Error code: %d.\n", errno);
                printf("%s",strc);
                logger(ClientFile,strc);
                return status;
            }
            snprintf(strc, sizeof strc, "> Disconnecting from %s:%d ...\n",hostname,port);
            printf("%s",strc);
            logger(ClientFile,strc);
        }
        //Exit
        else if (selection == 6)
            printf("> Exiting server...\n");
        else
            printf("> Enter your selection again\n");
        
    }
    fclose(ClientFile);
    return 0;
}