Abstracting a few features in the client and server. Adding additional overflow protection in splitting command and arguments.
parent
b3127887bd
commit
e8c09582d6
4
cftp.c
4
cftp.c
|
@ -54,7 +54,7 @@ void split_command(char *buffer, char *command, char *argument)
|
||||||
memset(argument, '\0', MSGLEN);
|
memset(argument, '\0', MSGLEN);
|
||||||
|
|
||||||
/* find everything up to the colon delimiter */
|
/* find everything up to the colon delimiter */
|
||||||
while(buffer[c] != '\0' && buffer[c] != ':')
|
while(buffer[c] != '\0' && buffer[c] != ':' && c < CMDLEN && d < CMDLEN)
|
||||||
{
|
{
|
||||||
command[d++] = buffer[c++];
|
command[d++] = buffer[c++];
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ void split_command(char *buffer, char *command, char *argument)
|
||||||
d = 0;
|
d = 0;
|
||||||
}
|
}
|
||||||
/* copy argument, if found */
|
/* copy argument, if found */
|
||||||
while(buffer[c] != '\0')
|
while(buffer[c] != '\0' && c < MSGLEN && d < MSGLEN)
|
||||||
{
|
{
|
||||||
argument[d++] = buffer[c++];
|
argument[d++] = buffer[c++];
|
||||||
}
|
}
|
||||||
|
|
71
client.c
71
client.c
|
@ -66,6 +66,44 @@ int connect_to_server(const char *address, int portnum)
|
||||||
return skt;
|
return skt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends a message to the socket. Pass in the socket and message. Expects msg
|
||||||
|
* to be already validated by validate_command first! Formats response into
|
||||||
|
* string buffer given.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void send_message(int skt, char *msg)
|
||||||
|
{
|
||||||
|
char command[CMDLEN], argument[MSGLEN], errmsg[ERRMSGLEN];
|
||||||
|
memset(command, '\0', CMDLEN);
|
||||||
|
memset(argument, '\0', MSGLEN);
|
||||||
|
memset(errmsg, '\0', ERRMSGLEN);
|
||||||
|
|
||||||
|
if(send(skt, msg, strlen(msg), 0) < 0)
|
||||||
|
{
|
||||||
|
sprintf(errmsg, "Send Error: %s", strerror(errno));
|
||||||
|
error(errmsg);
|
||||||
|
}
|
||||||
|
else if(recv(skt, msg, MSGLEN, 0) < 0)
|
||||||
|
{
|
||||||
|
sprintf(errmsg, "Receive Error: %s", strerror(errno));
|
||||||
|
error(errmsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
split_command(msg, command, argument);
|
||||||
|
if(strlen(argument) > 0)
|
||||||
|
{
|
||||||
|
sprintf(errmsg, "Response: %s: %s", command, argument);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(errmsg, "Response: %s", command);
|
||||||
|
}
|
||||||
|
cdebug(errmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Runs the command processor to the server. Handles commands and responses.
|
* Runs the command processor to the server. Handles commands and responses.
|
||||||
*
|
*
|
||||||
|
@ -73,13 +111,10 @@ int connect_to_server(const char *address, int portnum)
|
||||||
void run_client(const char *address, int portnum)
|
void run_client(const char *address, int portnum)
|
||||||
{
|
{
|
||||||
int skt;
|
int skt;
|
||||||
char msg[MSGLEN], command[CMDLEN], argument[MSGLEN];
|
char msg[MSGLEN];
|
||||||
|
|
||||||
/* clear strings */
|
|
||||||
memset(msg, '\0', MSGLEN);
|
memset(msg, '\0', MSGLEN);
|
||||||
memset(command, '\0', MSGLEN);
|
|
||||||
memset(argument, '\0', MSGLEN);
|
|
||||||
|
|
||||||
|
/* simple informational header */
|
||||||
sprintf(msg, "Using Server: %s:%d", address, portnum);
|
sprintf(msg, "Using Server: %s:%d", address, portnum);
|
||||||
cdebug(msg);
|
cdebug(msg);
|
||||||
memset(msg, '\0', MSGLEN);
|
memset(msg, '\0', MSGLEN);
|
||||||
|
@ -89,33 +124,13 @@ void run_client(const char *address, int portnum)
|
||||||
if(strlen(msg) > 0 && validate_command(msg))
|
if(strlen(msg) > 0 && validate_command(msg))
|
||||||
{
|
{
|
||||||
skt = connect_to_server(address, portnum);
|
skt = connect_to_server(address, portnum);
|
||||||
if(send(skt, msg, strlen(msg), 0) < 0)
|
send_message(skt, msg);
|
||||||
{
|
|
||||||
sprintf(msg, "Send Error: %s", strerror(errno));
|
|
||||||
error(msg);
|
|
||||||
}
|
|
||||||
else if(recv(skt, msg, MSGLEN, 0) < 0)
|
|
||||||
{
|
|
||||||
sprintf(msg, "Receive Error: %s", strerror(errno));
|
|
||||||
error(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
split_command(msg, command, argument);
|
|
||||||
if(strlen(argument) > 0)
|
|
||||||
{
|
|
||||||
sprintf(msg, "Server Said: %s: %s", command, argument);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(msg, "Server Said: %s", command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cdebug(msg);
|
|
||||||
close(skt);
|
close(skt);
|
||||||
}
|
}
|
||||||
else if(strlen(msg) > 0 && !strcmp(msg, "help"))
|
else if(strlen(msg) > 0 && !strcmp(msg, "help"))
|
||||||
{
|
{
|
||||||
|
sprintf(msg, "Using Server: %s:%d", address, portnum);
|
||||||
|
cdebug(msg);
|
||||||
cdebug("Available commands:");
|
cdebug("Available commands:");
|
||||||
cdebug(" * ping - returns an unix timestamp from the server");
|
cdebug(" * ping - returns an unix timestamp from the server");
|
||||||
cdebug(" * get:filename - gets a file, if possible");
|
cdebug(" * get:filename - gets a file, if possible");
|
||||||
|
|
50
server.c
50
server.c
|
@ -21,6 +21,30 @@ void sdebug(const char *msg)
|
||||||
debug("Server", msg);
|
debug("Server", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles each command received from the server. Expects that the message has
|
||||||
|
* been validated by validate_command first! Takes one parameter, the message
|
||||||
|
* from the client. The response is stored in the same buffer for return.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void server_command(char *msg)
|
||||||
|
{
|
||||||
|
char command[CMDLEN], argument[MSGLEN];
|
||||||
|
time_t pong;
|
||||||
|
memset(command, '\0', CMDLEN);
|
||||||
|
memset(argument, '\0', MSGLEN);
|
||||||
|
|
||||||
|
/* get individual command and argument for processing */
|
||||||
|
split_command(msg, command, argument);
|
||||||
|
|
||||||
|
/* now check each command and perform the expected results */
|
||||||
|
if(!strcmp(command, "ping"))
|
||||||
|
{
|
||||||
|
pong = time(NULL);
|
||||||
|
sprintf(msg, "Pong:%llud", (uintmax_t)pong);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proccesses a client connection and performs the necessary command. Called
|
* Proccesses a client connection and performs the necessary command. Called
|
||||||
* on each connection from a client.
|
* on each connection from a client.
|
||||||
|
@ -28,34 +52,22 @@ void sdebug(const char *msg)
|
||||||
*/
|
*/
|
||||||
void handle_client(int skt, const char *clientip)
|
void handle_client(int skt, const char *clientip)
|
||||||
{
|
{
|
||||||
char buffer[MSGLEN], msg[ERRMSGLEN], command[CMDLEN], argument[MSGLEN];
|
char buffer[MSGLEN], msg[ERRMSGLEN];
|
||||||
time_t pong;
|
|
||||||
memset(buffer, '\0', MSGLEN);
|
memset(buffer, '\0', MSGLEN);
|
||||||
memset(msg, '\0', ERRMSGLEN);
|
memset(msg, '\0', ERRMSGLEN);
|
||||||
memset(command, '\0', CMDLEN);
|
|
||||||
memset(argument, '\0', MSGLEN);
|
|
||||||
|
|
||||||
/* figure out what to do */
|
/* figure out what to do */
|
||||||
if(recv(skt, buffer, MSGLEN, 0) >= 0 && validate_command(buffer))
|
if(recv(skt, buffer, MSGLEN, 0) >= 0 && validate_command(buffer))
|
||||||
{
|
{
|
||||||
split_command(buffer, command, argument);
|
server_command(buffer);
|
||||||
if(!strcmp(command, "ping"))
|
}
|
||||||
{
|
else if(errno)
|
||||||
pong = time(NULL);
|
{
|
||||||
sprintf(buffer, "Pong:%llud", (uintmax_t)pong);
|
sprintf(buffer, "ERR:%s", strerror(errno));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(errno)
|
sprintf(buffer, "ERR:Invalid Command");
|
||||||
{
|
|
||||||
sprintf(buffer, "ERR:%s", strerror(errno));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(buffer, "ERR:Invalid Command");
|
|
||||||
}
|
|
||||||
error(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send message to client */
|
/* send message to client */
|
||||||
|
|
Reference in New Issue