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.