I managed to act as an FTP client in C just using sockets... Its really not too bad.
Now of course the client I made wasn't compatible with ALL ftp servers I am quite sure, I just needed to get it to connect to a solaris box. But it did work testing on some windows ftp server...
remember to wait for the server to send you ALL of the data it needs to, before your client starts spitting commands at it. Take a look at the return code numbers it sends you also. And one very important thing... Be sure to strcat(ftp_cmd,"\r\n"); before you send it, those are the termination characters...
i know its not the prettiest, but it works quite well. I plan on cleaning it up and making an example to throw out there for those who don't like 3rd party libraries...
PM or email me if you need anything else.
Now of course the client I made wasn't compatible with ALL ftp servers I am quite sure, I just needed to get it to connect to a solaris box. But it did work testing on some windows ftp server...
remember to wait for the server to send you ALL of the data it needs to, before your client starts spitting commands at it. Take a look at the return code numbers it sends you also. And one very important thing... Be sure to strcat(ftp_cmd,"\r\n"); before you send it, those are the termination characters...
Code:
int ftpRecvResponse(int sock, char * buf) {
int i;
if (recv(sock, buf, 5120, 0) == -1) {//receive the data
perror("recv");
return 0;;
}
for(i=(strlen(buf) - 1);i>0;i--) {
if(buf[i]=='.' || buf[i]=='\r') {
buf[i+1]='\0';
break;
}
}
printf("%s\n",buf); //print response to the screen
return 0;
}
int ftpNewCmd(int sock, char * buf, char * cmd, char * param) {
strcpy(buf,cmd);
if(strlen(param) > 0) {
strcat(buf," ");
strcat(buf,param);
}
strcat(buf,"\r\n");
printf("*%s",buf); //print the cmd to the screen
if(send(sock, buf, strlen(buf), 0) == -1) {
perror("send");
return 0;
}
//clear the buffer
return 0;
}
int ftpConvertAddy(char * buf, char * hostname, int * port) {
unsigned int i,t=0;
int flag=0,decCtr=0,tport1,tport2;
char tmpPort[6];
//example data in quotes below:
//"227 Listening on (149,122,52,162,4,20)"
//4 * 256 + 20 = 1044
for(i=0;i3)
hostname[i]='\0';
}
return 0;
}
int ftpSendFile(char * buf, char * host, int port) {
int sd;
struct sockaddr_in pin;
struct hostent *hp;
if ((hp = gethostbyname(host)) == 0) {
perror("gethostbyname");
return -1;
}
memset(&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
pin.sin_port = htons(port);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return -1;
}
if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) {
perror("connect");
return -1;
}
if(send(sd, buf, strlen(buf), 0) == -1) {
perror("send");
return -1;
}
closesocket(sd); //close the socket
return 0;
}
int ftpProcess(char *hostname, char *username, char *password, char *file, char *filename, char *path) {
int sd;
struct sockaddr_in pin;
struct hostent *hp;
char tmpHost[100];
int tmpPort;
char buf[5120];
if ((hp = gethostbyname(hostname)) == 0) {
perror("gethostbyname");
return -1;
}
memset(&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
pin.sin_port = htons(FTPPORT);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return -1;
}
if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) {
perror("connect");
return -1;
}
if(ftpRecvResponse(sd,buf)==1) { //wait for ftp server to start talking
if(strncmp(buf,"220",3)==0) { //make sure it ends with a 220
if(ftpNewCmd(sd,buf,"USER",username)==1) { //issue the command to login
if(ftpRecvResponse(sd,buf)==1) { //wait for response
if(strncmp(buf,"331",3)==0) { //make sure response is a 331
if(ftpNewCmd(sd,buf,"PASS",password)==1) { //send your password
if(ftpRecvResponse(sd,buf)==1) { //wait for response
if(strncmp(buf,"230",3)==0) { //make sure its a 230
if(ftpNewCmd(sd,buf,"PASV","")==1) { //notify server we want to pass a file
if(ftpRecvResponse(sd,buf)==1) { //wait for response
if(strncmp(buf,"227",3)==0) { //make sure it starts with a 227
ftpConvertAddy(buf,tmpHost,&tmpPort); //then convert the return to usable data
if(ftpNewCmd(sd,buf,"STOR",filename)==1) { //set the file name AND
ftpSendFile(file,tmpHost,tmpPort);
if(ftpRecvResponse(sd,buf)==1) { //wait for a response
if(strncmp(buf,"150",3)==0) { //make sure its a 150 so we know the server got it all
if(ftpRecvResponse(sd,buf)==1) {
if(strncmp(buf,"226",3)==0) {
.......
//close all if()s or do it some better way, close the socket when done.
i know its not the prettiest, but it works quite well. I plan on cleaning it up and making an example to throw out there for those who don't like 3rd party libraries...
PM or email me if you need anything else.
Last edited by mschoolbus : September 18th, 2003 at 03:08 PM.