Skip to content

Instantly share code, notes, and snippets.

@AlexFrazer
Created November 11, 2012 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexFrazer/0aa5a771c8ab518abbc7 to your computer and use it in GitHub Desktop.
Save AlexFrazer/0aa5a771c8ab518abbc7 to your computer and use it in GitHub Desktop.
/*
* Client FTP program
*
* Clientftp program
* sends and receieves messages with serverftp.
* Commands are: user, passwd, put, recv, ls, pwd, help, stat, mkdir, dele, rmdir
* @Crowz
*/
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define SERVER_FTP_PORT 1231
#define DATA_CONNECTION_PORT SERVER_FTP_PORT +1
/* Error and OK codes */
#define OK 0
#define ER_INVALID_HOST_NAME -1
#define ER_CREATE_SOCKET_FAILED -2
#define ER_BIND_FAILED -3
#define ER_CONNECT_FAILED -4
#define ER_SEND_FAILED -5
#define ER_RECEIVE_FAILED -6
/* Function prototypes */
int dataConnect(char *serverName, int *s);
int clntConnect(char *serverName, int *s);
int sendMessage (int s, char *msg, int msgSize);
int receiveMessage(int s, char *buffer, int bufferSize, int *msgSize);
int getDataSocket(int *s);
/* List of all global variables */
char userCmd[1024]; /* user typed ftp command line read from keyboard */
char cmd[1024]; /* ftp command extracted from userCmd */
char argument[1024]; /* argument extracted from userCmd */
char replyMsg[4096]; /* buffer to receive reply message from server */
char *space = " "; /*used to seperate arguments*/
/*
* main
*
* Function connects to the ftp server using clntConnect function.
* Reads one ftp command in one line from the keyboard into userCmd array.
* Sends the user command to the server.
* Receive reply message from the server.
* On receiving reply to QUIT ftp command from the server,
* close the control connection socket and exit from main
*
* Parameters
* argc - Count of number of arguments passed to main (input)
* argv - Array of pointer to input parameters to main (input)
* It is not required to pass any parameter to main
* Can use it if needed.
*
* Return status
* OK - Successful execution until QUIT command from client
* N - Failed status, value of N depends on the function called or cmd processed
*/
int main(
int argc,
char *argv[]
)
{
/* List of local varibale */
int ccSocket; /* Control connection socket - to be used in all client communication */
int msgSize; /* size of the reply message received from the server */
int status = OK;
/*
* NOTE: without \n at the end of format string in printf,
* UNIX will buffer (not flush)
* output to display and you will not see it on monitor.
*/
printf("Started execution of client ftp\n");
/* Connect to client ftp*/
printf("Calling clntConnect to connect to the server\n"); /* changed text */
status=clntConnect("127.0.0.1", &ccSocket); /* Off-campus IP: "143.241.37.230" */
if(status != 0)
{
printf("Connection to server failed, exiting main. \n");
return (status);
}
/*
* Read an ftp command with argument, if any, in one line from user into userCmd.
* Copy ftp command part into ftpCmd and the argument into arg array.
* Send the line read (both ftp cmd part and the argument part) in userCmd to server.
* Receive reply message from the server.
* until quit command is typed by the user.
*/
do
{
printf("my ftp> ");
gets(userCmd); /*reads the user command from the keyboard and stores in the variable userCmd*/
//printf("user command is %s\n", userCmd);
/* Separate command and argument from userCmd */
/* send the userCmd to the server */
status = sendMessage(ccSocket, userCmd, strlen(userCmd)+1);
if(status != OK)
{
break;
}
if(strstr(userCmd, " ")!=NULL) {
strcpy(cmd, strtok(userCmd, " "));
strcpy(argument, strtok(NULL, " "));
if(strcmp("put", cmd)==0) {
FILE *afile;
char buff[200];
int numberoffrigginbytes=0;
int data_socket;
//connect
status = getDataSocket(&data_socket);
if(status!=OK) printf("no");
data_socket=accept(data_socket, NULL, NULL);
//read file 200 bytes at a time
afile=fopen(argument, "r");
if(afile==NULL) {
sprintf(replyMsg, "that file does not exist");
fclose(afile);
} else {
while(!feof(afile)) {
numberoffrigginbytes=fread(buff, sizeof(char), sizeof(buff), afile);
status = sendMessage(data_socket, buff, strlen(buff));
//printf("%s",msgSize);
if(status!=OK) break;
}
fclose(afile);
}
close(data_socket);
}
else if(strcmp("recv", cmd)==0) {
char buff[200];
int data_socket;
//connect
status = getDataSocket(&data_socket);
data_socket=accept(data_socket, NULL, NULL);
//write a new file 200 bytes at a time
FILE *newfile;
newfile=fopen(argument, "w");
while(msgSize > 0) {
/**int i;
for(i=0; i<sizeof(buff); i++) {
buff[i]="q";
}*/
status=receiveMessage(data_socket,buff,sizeof(buff), &msgSize);
if(status!=OK) break;
fwrite(buff, sizeof(char), msgSize, newfile);
fflush(newfile);
//printf("%s",msgSize);
}
close(data_socket);
fclose(newfile);
}
}
/* Receive reply message from the the server */
status = receiveMessage(ccSocket, replyMsg, sizeof(replyMsg), &msgSize);
//printf("%s\n", replyMsg);
if(status != OK)
{
break;
}
} while (strcmp(userCmd, "quit") != 0);
printf("Closing control connection \n");
close(ccSocket); /* close control connection socket */
printf("Exiting client main \n");
return (status);
} /* end main() */
int dataConnect (
char *serverName, /* server IP address in dot notation (input) */
int *s /* control connection socket number (output) */
)
{
int sock; /* local variable to keep socket number */
struct sockaddr_in clientAddress; /* local client IP address */
struct sockaddr_in serverAddress; /* server IP address */
struct hostent *serverIPstructure; /* host entry having server IP address in binary */
/* Get IP address os server in binary from server name (IP in dot natation) */
if((serverIPstructure = gethostbyname(serverName)) == NULL)
{
printf("%s is unknown server. \n", serverName);
return (ER_INVALID_HOST_NAME); /* error return */
}
/* Create control connection socket */
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("cannot create socket ");
return (ER_CREATE_SOCKET_FAILED); /* error return */
}
/* initialize client address structure memory to zero */
memset((char *) &clientAddress, 0, sizeof(clientAddress));
/* Set local client IP address, and port in the address structure */
clientAddress.sin_family = AF_INET; /* Internet protocol family */
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR_ANY is 0, which means */
/* let the system fill client IP address */
clientAddress.sin_port = 0; /* With port set to 0, system will allocate a free port */
/* from 1024 to (64K -1) */
/* Associate the socket with local client IP address and port */
if(bind(sock,(struct sockaddr *)&clientAddress,sizeof(clientAddress))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/* Initialize serverAddress memory to 0 */
memset((char *) &serverAddress, 0, sizeof(serverAddress));
/* Set ftp server ftp address in serverAddress */
serverAddress.sin_family = AF_INET;
memcpy((char *) &serverAddress.sin_addr, serverIPstructure->h_addr,
serverIPstructure->h_length);
serverAddress.sin_port = htons(DATA_CONNECTION_PORT);
/* Connect to the server */
if (connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
{
perror("Cannot connect to server ");
close (sock); /* close the control connection socket */
return(ER_CONNECT_FAILED); /* error return */
}
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK); /* successful return */
} // end of clntConnect() */
/*
* clntConnect
*
* Function to create a socket, bind local client IP address and port to the socket
* and connect to the server
*
* Parameters
* serverName - IP address of server in dot notation (input)
* s - Control connection socket number (output)
*
* Return status
* OK - Successfully connected to the server
* ER_INVALID_HOST_NAME - Invalid server name
* ER_CREATE_SOCKET_FAILED - Cannot create socket
* ER_BIND_FAILED - bind failed
* ER_CONNECT_FAILED - connect failed
*/
int clntConnect (
char *serverName, /* server IP address in dot notation (input) */
int *s /* control connection socket number (output) */
)
{
int sock; /* local variable to keep socket number */
struct sockaddr_in clientAddress; /* local client IP address */
struct sockaddr_in serverAddress; /* server IP address */
struct hostent *serverIPstructure; /* host entry having server IP address in binary */
/* Get IP address os server in binary from server name (IP in dot natation) */
if((serverIPstructure = gethostbyname(serverName)) == NULL)
{
printf("%s is unknown server. \n", serverName);
return (ER_INVALID_HOST_NAME); /* error return */
}
/* Create control connection socket */
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("cannot create socket ");
return (ER_CREATE_SOCKET_FAILED); /* error return */
}
/* initialize client address structure memory to zero */
memset((char *) &clientAddress, 0, sizeof(clientAddress));
/* Set local client IP address, and port in the address structure */
clientAddress.sin_family = AF_INET; /* Internet protocol family */
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR_ANY is 0, which means */
/* let the system fill client IP address */
clientAddress.sin_port = 0; /* With port set to 0, system will allocate a free port */
/* from 1024 to (64K -1) */
/* Associate the socket with local client IP address and port */
if(bind(sock,(struct sockaddr *)&clientAddress,sizeof(clientAddress))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/* Initialize serverAddress memory to 0 */
memset((char *) &serverAddress, 0, sizeof(serverAddress));
/* Set ftp server ftp address in serverAddress */
serverAddress.sin_family = AF_INET;
memcpy((char *) &serverAddress.sin_addr, serverIPstructure->h_addr,
serverIPstructure->h_length);
serverAddress.sin_port = htons(SERVER_FTP_PORT);
/* Connect to the server */
if (connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
{
perror("Cannot connect to server ");
close (sock); /* close the control connection socket */
return(ER_CONNECT_FAILED); /* error return */
}
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK); /* successful return */
} // end of clntConnect() */
/*
* sendMessage
*
* Function to send specified number of octet (bytes) to client ftp
*
* Parameters
* s - Socket to be used to send msg to client (input)
* msg - Pointer to character arrary containing msg to be sent (input)
* msgSize - Number of bytes, including NULL, in the msg to be sent to client (input)
*
* Return status
* OK - Msg successfully sent
* ER_SEND_FAILED - Sending msg failed
*/
int sendMessage(
int s, /* socket to be used to send msg to client */
char *msg, /*buffer having the message data */
int msgSize /*size of the message/data in bytes */
)
{
//int i;
/* Print the message to be sent byte by byte as character
for(i=0;i<msgSize;i++)
{
printf("%c",msg[i]);
}
printf("\n");*/
if((send(s,msg,msgSize,0)) < 0) /* socket interface call to transmit */
{
perror("unable to send ");
return(ER_SEND_FAILED);
}
return(OK); /* successful send */
}
/*
* receiveMessage
*
* Function to receive message from client ftp
*
* Parameters
* s - Socket to be used to receive msg from client (input)
* buffer - Pointer to character arrary to store received msg (input/output)
* bufferSize - Maximum size of the array, "buffer" in octent/byte (input)
* This is the maximum number of bytes that will be stored in buffer
* msgSize - Actual # of bytes received and stored in buffer in octet/byes (output)
*
* Return status
* OK - Msg successfully received
* ER_RECEIVE_FAILED - Receiving msg failed
*/
int receiveMessage (
int s, /* socket */
char *buffer, /* buffer to store received msg */
int bufferSize, /* how large the buffer is in octet */
int *msgSize /* size of the received msg in octet */
)
{
int i;
*msgSize=recv(s,buffer,bufferSize,0); /* socket interface call to receive msg */
if(*msgSize<0)
{
perror("unable to receive");
return(ER_RECEIVE_FAILED);
}
/* Print the received msg byte by byte */
for(i=0;i<*msgSize;i++)
{
printf("%c", buffer[i]);
}
printf("\n");
return (OK);
}
/*
* clntExtractReplyCode
*
* Function to extract the three digit reply code
* from the server reply message received.
* It is assumed that the reply message string is of the following format
* ddd text
* where ddd is the three digit reply code followed by or or more space.
*
* Parameters
* buffer - Pointer to an array containing the reply message (input)
* replyCode - reply code number (output)
*
* Return status
* OK - Successful (returns always success code
*/
int clntExtractReplyCode (
char *buffer, /* Pointer to an array containing the reply message (input) */
int *replyCode /* reply code (output) */
)
{
/* extract the codefrom the server reply message */
sscanf(buffer, "%d", replyCode);
return (OK);
} // end of clntExtractReplyCode()
int getDataSocket (int *s)
{
int sock;
struct sockaddr_in svcAddr;
int qlen;
if( (sock=socket(AF_INET, SOCK_STREAM,0)) <0)
{
perror("cannot create socket");
return(ER_CREATE_SOCKET_FAILED);
}
memset((char *)&svcAddr,0, sizeof(svcAddr));
/* initialize svcAddr to have server IP address and server listen port#. */
svcAddr.sin_family = AF_INET;
svcAddr.sin_addr.s_addr=htonl(INADDR_ANY);
svcAddr.sin_port=htons(DATA_CONNECTION_PORT);
/* bind (associate) the listen socket number with server IP and port#.
* bind is a socket interface function
*/
if(bind(sock,(struct sockaddr *)&svcAddr,sizeof(svcAddr))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/*
* Set listen queue length to 1 outstanding connection request.
* This allows 1 outstanding connect request from client to wait
* while processing current connection request, which takes time.
* It prevents connection request to fail and client to think server is down
* when in fact server is running and busy processing connection request.
*/
qlen=1;
/*
* Listen for connection request to come from client ftp.
* This is a non-blocking socket interface function call,
* meaning, server ftp execution does not block by the 'listen' funcgtion call.
* Call returns right away so that server can do whatever it wants.
* The TCP transport layer will continuously listen for request and
* accept it on behalf of server ftp when the connection requests comes.
*/
listen(sock,qlen); /* socket interface function call */
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK);
}
/*
* server FTP program
*
* NOTE: Starting homework #2, add more comments here describing the overall function
* performed by server ftp program
* This includes, the list of ftp commands processed by server ftp.
*
*/
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
//data ports for transfer
#define SERVER_FTP_PORT 1231
#define DATA_CONNECTION_PORT SERVER_FTP_PORT +1
/* Error and OK codes */
#define OK 0
#define ER_INVALID_HOST_NAME -1
#define ER_CREATE_SOCKET_FAILED -2
#define ER_BIND_FAILED -3
#define ER_CONNECT_FAILED -4
#define ER_SEND_FAILED -5
#define ER_RECEIVE_FAILED -6
#define ER_ACCEPT_FAILED -7
/* Function prototypes */
int getDataSocket(int *s);
int svcInitServer(int *s);
int sendMessage (int s, char *msg, int msgSize);
int receiveMessage(int s, char *buffer, int bufferSize, int *msgSize);
int dataConnect(char *servername, int *s);
/* List of all global variables */
char userCmd[1024]; /* user typed ftp command line received from client */
char cmd[1024]; /* ftp command (without argument) extracted from userCmd */
char argument[1024]; /* argument (without ftp command) extracted from userCmd */
char replyMsg[4096]; /* buffer to send reply message to client */
char *space=" ";
char buffer[4096];
FILE *myfile;
char users[1024]; /* the list of users */
char user[1024];
char pass[1024];
/*
* main
*
* Function to listen for connection request from client
* Receive ftp command one at a time from client
* Process received command
* Send a reply message to the client after processing the command with staus of
* performing (completing) the command
* On receiving QUIT ftp command, send reply to client and then close all sockets
*
* Parameters
* argc - Count of number of arguments passed to main (input)
* argv - Array of pointer to input parameters to main (input)
* It is not required to pass any parameter to main
* Can use it if needed.
*
* Return status
* 0 - Successful execution until QUIT command from client
* ER_ACCEPT_FAILED - Accepting client connection request failed
* N - Failed stauts, value of N depends on the command processed
*/
int main(
int argc,
char *argv[]
)
{
/* List of local varibale */
int msgSize; /* Size of msg received in octets (bytes) */
int listenSocket; /* listening server ftp socket for client connect request */
int ccSocket; /* Control connection socket - to be used in all client communication */
int status;
/*
* NOTE: without \n at the end of format string in printf,
* UNIX will buffer (not flush)
* output to display and you will not see it on monitor.
*/
printf("Started execution of server ftp\n");
/*initialize server ftp*/
printf("Initialize ftp server\n"); /* changed text */
status=svcInitServer(&listenSocket);
if(status != 0)
{
printf("Exiting server ftp due to svcInitServer returned error\n");
exit(status);
}
printf("ftp server is waiting to accept connection\n");
/* wait until connection request comes from client ftp */
ccSocket = accept(listenSocket, NULL, NULL);
printf("Came out of accept() function \n");
if(ccSocket < 0)
{
perror("cannot accept connection:");
printf("Server ftp is terminating after closing listen socket.\n");
close(listenSocket); /* close listen socket */
return (ER_ACCEPT_FAILED); // error exist
}
printf("Connected to client, calling receiveMsg to get ftp cmd from client \n");
/* Receive and process ftp commands from client until quit command.
* On receiving quit command, send reply to client and
* then close the control connection socket "ccSocket".
*/
do
{
/* Receive client ftp commands until */
status=receiveMessage(ccSocket, userCmd, sizeof(userCmd), &msgSize);
//printf("userCmd is ", userCmd);
if(status < 0)
{
printf("Receive message failed. Closing control connection \n");
printf("Server ftp is terminating.\n");
break;
}
/* Separate command and argument from userCmd */
if(strchr(userCmd,' ')==NULL) strcpy(cmd,userCmd);
else {
strcpy(cmd, strtok(userCmd, space));
strcpy(argument, strtok(NULL, space));
printf("user command is %s\n", cmd);
printf("argument is %s\n", argument);
}
/* pseudo list of users and password */
strcpy(users, "alex password\n"
"Peter derp\n"
"Freya beauty\n"
"AdamJensen INeverAskedForThis\n");
//pwd command
if(strcmp(cmd, "pwd")==0) {
memset(buffer,'\0',sizeof(buffer)); //make sure buffer is clear
system("pwd > /tmp/pwd.txt");
/** read the file to a buffer */
myfile=fopen("/tmp/pwd.txt","r");
status = fread(buffer, sizeof(buffer), sizeof(char), myfile);
sprintf(replyMsg, "cmd 250 okay %s\n", buffer);
fclose(myfile);
//delete the txt file
system("rm /tmp/pwd.txt");
}
//ls command
else if(strcmp(cmd, "ls")==0) {
memset(buffer,'\0',sizeof(buffer)); //make sure the buffer is clear
system("ls > /tmp/ls.txt");
// read into a buffer to be sent
myfile=fopen("/tmp/ls.txt","r");
status = fread(buffer, sizeof(buffer), sizeof(char), myfile);
sprintf(replyMsg, "cmd 250 okay \n%s\n",buffer);
fclose(myfile);
//remove the file
system("rm /tmp/ls.txt");
}
else if(strcmp(cmd, "mkdir")==0) {
memset(buffer,'\0',sizeof(buffer)); //make sure buffer is clear
//check if there is an argument, if not, report error
if(strlen(argument)==0) {
printf("no argument supplied. Please retry with argument");
//reset the command and argument
memset(cmd,'\0',sizeof(cmd));
memset(argument,'\0',sizeof(argument));
}
char subcommand[1024];
memset(replyMsg,'\0',sizeof(replyMsg));
sprintf(subcommand, "mkdir %s", argument);
//make a system call to make the new directory
status= system(subcommand);
sprintf(replyMsg, "cmd 212 successfully created dir %s\n", argument);
memset(cmd,'\0',sizeof(cmd));
memset(argument, '\0',sizeof(cmd));
}
else if(strcmp(cmd, "rmdir")==0) {
char subcommand[1024];
memset(replyMsg,'\0', sizeof(replyMsg));
//check if there is an argument. If not, send a new error message.
if(strlen(argument)==0) {
sprintf(replyMsg, "no argument supplied. rmdir requires an argument\n");
}
sprintf(subcommand, "rmdir %s", argument);
//system call to remove the directory
status=system(subcommand);
if(status < 0) {
sprintf(replyMsg, "error; try again.\n");
}
sprintf(replyMsg, "cmd 212 successfully removed %s\n", argument);
memset(cmd,'\0',sizeof(cmd));
memset(argument,'\0',sizeof(argument));
}
//rm function
else if(strcmp(cmd, "dele")==0) {
char subcommand[1024];
memset(replyMsg, '\0', sizeof(replyMsg));
//make sure there's an argument, if not, new error message.
if(strlen(argument)==0) {
sprintf(replyMsg, "error; no argument supplied\n");
}
sprintf(subcommand,"rm %s", argument);
//system call to delete the file
status=system(subcommand);
//if it does not return an OK status, send a new error
if( status < 0 ) {
sprintf(replyMsg, "error occured\n");
}
sprintf(replyMsg, "cmd 211 okay, deleted %s\n", argument);
memset(cmd,'\0',sizeof(cmd));
memset(argument, '\0',sizeof(argument));
}
else if(strcmp(cmd, "cd")==0) {
memset(replyMsg, '\0', sizeof(replyMsg));
status= chdir(argument);
if(status < 0) {
sprintf(replyMsg, "that directory does not exist\n");
}
memset(cmd,'\0',sizeof(cmd));
memset(argument, '\0', sizeof(argument));
/* in order to move backwards in a directory */
}
else if(strcmp(cmd, "stat")==0) {
memset(replyMsg, '\0', sizeof(replyMsg));
memset(buffer,'\0',sizeof(buffer));
if(strlen(argument)>0) {
printf("there is no need for arguments with this command");
}
system("stat > /tmp/stat.txt");
myfile=fopen("/tmp/stat.txt", "r");
fread(buffer, sizeof(buffer), sizeof(char), myfile);
strcpy(replyMsg, buffer);
fclose(myfile);
system("rm /tmp/stat.txt");
}
//print users
else if(strcmp(cmd, "user")==0) {
char line[1024];
char * theline;
int found=0;
//to make sure users isn't overwritten, make a new variable.
strcpy (line, users);
theline= strtok(line, "\n");
do {
printf("line: %s\n", theline);
sscanf(theline, "%s %s", user, pass);
if(strcmp(argument, user)==0) {
sprintf(replyMsg, "cmd 331 name okay, need password \n");
found=1;
break;
}
theline= strtok(NULL, "\n");
memset(replyMsg, '\0', sizeof(replyMsg));
} while ( theline!=NULL );
if( found==0 ){ sprintf(replyMsg, "cmd 332 that user doesn't exist, like Santa or George Washington.\n"); }
}
//this command simply copies the program's commands into the replyMsg
else if(strcmp(cmd, "help")==0) {
strcpy(replyMsg, "Commands\t Use \t\t\t Syntax\n"
"pwd \t\t print directory \t pwd\n"
"cd \t\t change directory \t cd dir\n"
"dele \t\t remove a file \t dele file\n"
"stat \t\t print stats \t stat\n"
"mkdir\t\t make a directory \t mkdir dir\n"
"rmdir\t\t remove directory \t rmdir dir\n"
"ls \t\t print files in dir\t ls\n"
"pass \t\t log in password \t password pass\n"
"user \t\t log in as user \t username user\n"
);
}
else if(strcmp(cmd, "pass")==0) {
memset(replyMsg, '\0', sizeof(replyMsg));
if(pass[0]=='\0') sprintf(replyMsg, "cmd 332 need account for login\n");
if(strcmp(argument, pass)==0) sprintf(replyMsg, "cmd 231 password correct");
else sprintf(replyMsg, "password incorrect");
}
//pass a replyMsg
else if(strcmp(cmd, "quit")==0) {
memset(replyMsg, '\0', sizeof(replyMsg));
strcpy(replyMsg, "cmd 231 okay, user logged out\n");
} else if(strcmp("recv", cmd)==0) {
FILE *afile;
char buff[200];
int data_socket;
//connect to an IP
dataConnect("127.0.0.1", &data_socket);
afile=fopen(argument, "r");
//check if file exists, if it does, read 200 chars at a time
if(afile==NULL) {
sprintf(replyMsg,"that file does not exist");
fclose(afile);
} else {
while(!feof(afile)) {
/**int i;
for(i=0; i<sizeof(buff); i++) {
buff[i]="q";
}*/
fread(buff, sizeof(char), sizeof(buff), afile);
status = sendMessage(data_socket, buff, strlen(buff));
if(status!=OK) break;
//printf("%s",msgSize);
}
printf("finished");
fclose(afile);
}
close(data_socket);
fclose(afile);
}
else if(strcmp("put", cmd)==0) {
memset(replyMsg, '\0', sizeof(replyMsg));
char buff[200];
int s;
dataConnect("127.0.0.1", &s);
FILE *newfile;
//if(fopen(argument, "r")!=NULL) {
newfile=fopen(argument, "w");
//while getting messages, write to a file
while(msgSize>0) {
status=receiveMessage(s,buff,sizeof(buff), &msgSize);
fwrite(buff, sizeof(char), msgSize, newfile);
//printf("%s",msgSize);
fflush(newfile);
}
printf("finished");
close(s);
fclose(newfile);
} else {
sprintf(replyMsg, "cmd 202 that is not a valid command\n");
}
/*
* ftp server sends only one reply message to the client for
* each command received in this implementation.
*/
//strcpy(replyMsg,"200 cmd okay\n"); /* Should have appropriate reply msg starting HW2 */
status=sendMessage(ccSocket,replyMsg,strlen(replyMsg) + 1); /* Added 1 to include NULL character in */
/* the reply string strlen does not count NULL character */
if(status < 0)
{
break; /* exit while loop */
}
}
while(strcmp(cmd, "quit") != 0);
printf("Closing control connection socket.\n");
close (ccSocket); /* Close client control connection socket */
printf("Closing listen socket.\n");
close(listenSocket); /*close listen socket */
printf("Existing from server ftp main \n");
return (status);
}
/*
* svcInitServer
*
* Function to create a socket and to listen for connection request from client
* using the created listen socket.
*
* Parameters
* s - Socket to listen for connection request (output)
*
* Return status
* OK - Successfully created listen socket and listening
* ER_CREATE_SOCKET_FAILED - socket creation failed
*/
int dataConnect (
char *serverName, /* server IP address in dot notation (input) */
int *s /* control connection socket number (output) */
)
{
int sock; /* local variable to keep socket number */
struct sockaddr_in clientAddress; /* local client IP address */
struct sockaddr_in serverAddress; /* server IP address */
struct hostent *serverIPstructure; /* host entry having server IP address in binary */
/* Get IP address os server in binary from server name (IP in dot natation) */
if((serverIPstructure = gethostbyname(serverName)) == NULL)
{
printf("%s is unknown server. \n", serverName);
return (ER_INVALID_HOST_NAME); /* error return */
}
/* Create control connection socket */
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("cannot create socket ");
return (ER_CREATE_SOCKET_FAILED); /* error return */
}
/* initialize client address structure memory to zero */
memset((char *) &clientAddress, 0, sizeof(clientAddress));
/* Set local client IP address, and port in the address structure */
clientAddress.sin_family = AF_INET; /* Internet protocol family */
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR_ANY is 0, which means */
/* let the system fill client IP address */
clientAddress.sin_port = 0; /* With port set to 0, system will allocate a free port */
/* from 1024 to (64K -1) */
/* Associate the socket with local client IP address and port */
if(bind(sock,(struct sockaddr *)&clientAddress,sizeof(clientAddress))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/* Initialize serverAddress memory to 0 */
memset((char *) &serverAddress, 0, sizeof(serverAddress));
/* Set ftp server ftp address in serverAddress */
serverAddress.sin_family = AF_INET;
memcpy((char *) &serverAddress.sin_addr, serverIPstructure->h_addr,
serverIPstructure->h_length);
serverAddress.sin_port = htons(DATA_CONNECTION_PORT);
/* Connect to the server */
if (connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
{
perror("Cannot connect to server ");
close (sock); /* close the control connection socket */
return(ER_CONNECT_FAILED); /* error return */
}
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK); /* successful return */
}
int svcInitServer (
int *s /*Listen socket number returned from this function */
)
{
int sock;
struct sockaddr_in svcAddr;
int qlen;
/*create a socket endpoint */
if( (sock=socket(AF_INET, SOCK_STREAM,0)) <0)
{
perror("cannot create socket");
return(ER_CREATE_SOCKET_FAILED);
}
/*initialize memory of svcAddr structure to zero. */
memset((char *)&svcAddr,0, sizeof(svcAddr));
/* initialize svcAddr to have server IP address and server listen port#. */
svcAddr.sin_family = AF_INET;
svcAddr.sin_addr.s_addr=htonl(INADDR_ANY); /* server IP address */
svcAddr.sin_port=htons(SERVER_FTP_PORT); /* server listen port # */
/* bind (associate) the listen socket number with server IP and port#.
* bind is a socket interface function
*/
if(bind(sock,(struct sockaddr *)&svcAddr,sizeof(svcAddr))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/*
* Set listen queue length to 1 outstanding connection request.
* This allows 1 outstanding connect request from client to wait
* while processing current connection request, which takes time.
* It prevents connection request to fail and client to think server is down
* when in fact server is running and busy processing connection request.
*/
qlen=1;
/*
* Listen for connection request to come from client ftp.
* This is a non-blocking socket interface function call,
* meaning, server ftp execution does not block by the 'listen' funcgtion call.
* Call returns right away so that server can do whatever it wants.
* The TCP transport layer will continuously listen for request and
* accept it on behalf of server ftp when the connection requests comes.
*/
listen(sock,qlen); /* socket interface function call */
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK); /*successful return */
}
/*
* sendMessage
*
* Function to send specified number of octet (bytes) to client ftp
*
* Parameters
* s - Socket to be used to send msg to client (input)
* msg - Pointer to character arrary containing msg to be sent (input)
* msgSize - Number of bytes, including NULL, in the msg to be sent to client (input)
*
* Return status
* OK - Msg successfully sent
* ER_SEND_FAILED - Sending msg failed
*/
int sendMessage(
int s, /* socket to be used to send msg to client */
char *msg, /* buffer having the message data */
int msgSize /* size of the message/data in bytes */
)
{
int i;
/* Print the message to be sent byte by byte as character */
for(i=0; i<msgSize; i++)
{
printf("%c",msg[i]);
}
printf("\n");
if((send(s, msg, msgSize, 0)) < 0) /* socket interface call to transmit */
{
perror("unable to send ");
return(ER_SEND_FAILED);
}
return(OK); /* successful send */
}
/*
* receiveMessage
*
* Function to receive message from client ftp
*
* Parameters
* s - Socket to be used to receive msg from client (input)
* buffer - Pointer to character arrary to store received msg (input/output)
* bufferSize - Maximum size of the array, "buffer" in octent/byte (input)
* This is the maximum number of bytes that will be stored in buffer
* msgSize - Actual # of bytes received and stored in buffer in octet/byes (output)
*
* Return status
* OK - Msg successfully received
* R_RECEIVE_FAILED - Receiving msg failed
*/
int receiveMessage (
int s, /* socket */
char *buffer, /* buffer to store received msg */
int bufferSize, /* how large the buffer is in octet */
int *msgSize /* size of the received msg in octet */
)
{
int i;
*msgSize=recv(s,buffer,bufferSize,0); /* socket interface call to receive msg */
if(*msgSize<0)
{
perror("unable to receive");
return(ER_RECEIVE_FAILED);
}
/* Print the received msg byte by byte */
for(i=0;i<*msgSize;i++)
{
printf("%c", buffer[i]);
}
printf("\n");
return (OK);
}
int getDataSocket (int *s)
{
int sock;
struct sockaddr_in svcAddr;
int qlen;
if( (sock=socket(AF_INET, SOCK_STREAM,0)) <0)
{
perror("cannot create socket");
return(ER_CREATE_SOCKET_FAILED);
}
memset((char *)&svcAddr,0, sizeof(svcAddr));
/* initialize svcAddr to have server IP address and server listen port#. */
svcAddr.sin_family = AF_INET;
svcAddr.sin_addr.s_addr=htonl(INADDR_ANY);
svcAddr.sin_port=htons(DATA_CONNECTION_PORT+1);
/* bind (associate) the listen socket number with server IP and port#.
* bind is a socket interface function
*/
if(bind(sock,(struct sockaddr *)&svcAddr,sizeof(svcAddr))<0)
{
perror("cannot bind");
close(sock);
return(ER_BIND_FAILED); /* bind failed */
}
/*
* Set listen queue length to 1 outstanding connection request.
* This allows 1 outstanding connect request from client to wait
* while processing current connection request, which takes time.
* It prevents connection request to fail and client to think server is down
* when in fact server is running and busy processing connection request.
*/
qlen=1;
/*
* Listen for connection request to come from client ftp.
* This is a non-blocking socket interface function call,
* meaning, server ftp execution does not block by the 'listen' funcgtion call.
* Call returns right away so that server can do whatever it wants.
* The TCP transport layer will continuously listen for request and
* accept it on behalf of server ftp when the connection requests comes.
*/
listen(sock,qlen); /* socket interface function call */
/* Store listen socket number to be returned in output parameter 's' */
*s=sock;
return(OK); /*successful return */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment