18471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma/* ftpget.c - Get a remote file from FTP. 28471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * 38471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * Copyright 2013 Ranjan Kumar <ranjankumar.bth@gmail.com> 48471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * Copyright 2013 Kyungwan Han <asura321@gmail.com> 58471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * 68471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * No Standard. 78471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * 8fc33eb78115adf8a90875f822706bdf3d462524cIsaac DunhamUSE_FTPGET(NEWTOY(ftpget, "<2cvu:p:P#<0=21>65535", TOYFLAG_BIN)) 9f3e56f4e4ff773de95fa2c9daf979734d826fc33Rob LandleyUSE_FTPGET(OLDTOY(ftpput, ftpget, TOYFLAG_BIN)) 108471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 118471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmaconfig FTPGET 128471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma bool "ftpget/ftpput" 138471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma default n 148471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma help 15fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham usage: ftpget [-cv] [-u USER -p PASSWORD -P PORT] HOST_NAME [LOCAL_FILENAME] REMOTE_FILENAME 16fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham usage: ftpput [-v] [-u USER -p PASSWORD -P PORT] HOST_NAME [REMOTE_FILENAME] LOCAL_FILENAME 178471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 188471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma ftpget - Get a remote file from FTP. 198471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma ftpput - Upload a local file on remote machine through FTP. 208471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 218471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma -c Continue previous transfer. 228471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma -v Verbose. 238471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma -u User name. 248471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma -p Password. 25fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham -P Port Number (default 21). 268471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma*/ 278471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define FOR_ftpget 288471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#include "toys.h" 298471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 308471dc08c411822480b2bf622a5ea7fce1cef33dAshwini SharmaGLOBALS( 31fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham long port; // char *port; 328471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char *password; 338471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char *username; 348471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 358471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma FILE *sockfp; 368471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int c; 378471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int isget; 388471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char buf[sizeof(struct sockaddr_storage)]; 398471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma) 408471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 418471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define DATACONNECTION_OPENED 125 428471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define FTPFILE_STATUSOKAY 150 438471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define FTP_COMMAND_OKAY 200 448471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define FTPFILE_STATUS 213 458471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define FTPSERVER_READY 220 468471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define CLOSE_DATACONECTION 226 478471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define PASSIVE_MODE 227 488471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define USERLOGGED_SUCCESS 230 498471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define PASSWORD_REQUEST 331 508471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma#define REQUESTED_PENDINGACTION 350 518471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 528471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 538471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void setport(unsigned port_num) 548471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 558471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int af = ((struct sockaddr *)TT.buf)->sa_family; 568471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 578471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (af == AF_INET) ((struct sockaddr_in*)TT.buf)->sin_port = port_num; 588471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma else if (af == AF_INET6) ((struct sockaddr_in6*)TT.buf)->sin6_port = port_num; 598471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 608471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 618471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic int connect_to_stream() 628471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 638471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int sockfd, af = ((struct sockaddr *)TT.buf)->sa_family; 648471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 658471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma sockfd = xsocket(af, SOCK_STREAM, 0); 668471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (connect(sockfd, (struct sockaddr*)TT.buf,((af == AF_INET)? 678471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6))) < 0) { 688471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma close(sockfd); 698471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma perror_exit("can't connect to remote host"); 708471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } 718471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma return sockfd; 728471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 738471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 748471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma//close ftp connection and print the message. 758471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void close_stream(char *msg_str) 768471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 778471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char *str = toybuf; //toybuf holds response data. 788471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 798471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //Remove garbage chars (from ' ' space to '\x7f') DEL remote server response. 808471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma while ((*str >= 0x20) && (*str < 0x7f)) str++; 818471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma *str = '\0'; 828471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (TT.sockfp) fclose(TT.sockfp); 838471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma error_exit("%s server response: %s", (msg_str) ? msg_str:"", toybuf); 848471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 858471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 868471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma//send command to ftp and get return status. 878471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic int get_ftp_response(char *command, char *param) 888471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 898471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma unsigned cmd_status = 0; 908471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char *fmt = "%s %s\r\n"; 918471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 928471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (command) { 938471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (!param) fmt += 3; 948471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma fprintf(TT.sockfp, fmt, command, param); 958471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma fflush(TT.sockfp); 968471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (toys.optflags & FLAG_v) 978471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma fprintf(stderr, "FTP Request: %s %s\r\n", command, param); 988471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } 998471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1008471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma do { 1018471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (!fgets(toybuf, sizeof(toybuf)-1, TT.sockfp)) close_stream(NULL); 1028471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } while (!isdigit(toybuf[0]) || toybuf[3] != ' '); 1038471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1048471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma toybuf[3] = '\0'; 1058471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma cmd_status = atolx_range(toybuf, 0, INT_MAX); 1068471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma toybuf[3] = ' '; 1078471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma return cmd_status; 1088471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 1098471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1108471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void send_requests(void) 1118471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 1128471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int cmd_status = 0; 1138471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1148471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //FTP connection request. 1158471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response(NULL, NULL) != FTPSERVER_READY) close_stream(NULL); 1168471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1178471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //230 User authenticated, password please; 331 Password request. 1188471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma cmd_status = get_ftp_response("USER", TT.username); 1198471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (cmd_status == PASSWORD_REQUEST) { //user logged in. Need Password. 1208471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response("PASS", TT.password) != USERLOGGED_SUCCESS) 1218471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma close_stream("PASS"); 1228471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } else if (cmd_status == USERLOGGED_SUCCESS); //do nothing 1238471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma else close_stream("USER"); 1248471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //200 Type Binary. Command okay. 1258471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response("TYPE I", NULL) != FTP_COMMAND_OKAY) 1268471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma close_stream("TYPE I"); 1278471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 1288471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1298471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void get_sockaddr(char *host) 1308471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 1318471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma struct addrinfo hints, *result; 13230f6ef5fcd571c554c2c59585d126b92793379d0Ashwini Sharma char port[6]; 133fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham int status; 1348471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1358471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma errno = 0; 136fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham snprintf(port, 6, "%ld", TT.port); 1378471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1388471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma memset(&hints, 0 , sizeof(struct addrinfo)); 1398471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma hints.ai_family = AF_UNSPEC; 1408471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma hints.ai_socktype = SOCK_STREAM; 1418471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 142fc33eb78115adf8a90875f822706bdf3d462524cIsaac Dunham status = getaddrinfo(host, port, &hints, &result); 1438471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (status) error_exit("bad address '%s' : %s", host, gai_strerror(status)); 1448471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1458471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma memcpy(TT.buf, result->ai_addr, result->ai_addrlen); 1468471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma freeaddrinfo(result); 1478471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 1488471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1498471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma// send commands to ftp fo PASV mode. 1508471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void verify_pasv_mode(char *r_filename) 1518471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 1528471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char *pch; 1538471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma unsigned portnum; 1548471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1558471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //vsftpd reply like:- "227 Entering Passive Mode (125,19,39,117,43,39)". 1567eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma if (get_ftp_response("PASV", NULL) != PASSIVE_MODE) goto close_stream; 1578471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1588471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //Response is "NNN <some text> (N1,N2,N3,N4,P1,P2) garbage. 1598471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //Server's IP is N1.N2.N3.N4 1608471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //Server's port for data connection is P1*256+P2. 1617eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma if (!(pch = strrchr(toybuf, ')'))) goto close_stream; 1627eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma *pch = '\0'; 1637eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma if (!(pch = strrchr(toybuf, ','))) goto close_stream; 1647eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma *pch = '\0'; 1657eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma 1668471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma portnum = atolx_range(pch + 1, 0, 255); 1678471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1687eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma if (!(pch = strrchr(toybuf, ','))) goto close_stream; 1697eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma *pch = '\0'; 1708471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma portnum = portnum + (atolx_range(pch + 1, 0, 255) * 256); 1718471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma setport(htons(portnum)); 1728471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1738471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (TT.isget && get_ftp_response("SIZE", r_filename) != FTPFILE_STATUS) 1748471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.c = 0; 1757eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma return; 1767eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma 1777eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharmaclose_stream: 1787eb3e4364c2bcebd2fdfef52c07f5101aa03e5bbAshwini Sharma close_stream("PASV"); 1798471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 1808471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1818471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma/* 1828471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * verify the local file presence. 1838471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma * if present, get the size of the file. 1848471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma */ 1858471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void is_localfile_present(char *l_filename) 1868471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 1878471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma struct stat sb; 1888471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1898471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (stat(l_filename, &sb) < 0) perror_exit("stat"); 1908471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if local file present, then request for pending file action. 1918471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (sb.st_size > 0) { 1928471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma sprintf(toybuf, "REST %lu", (unsigned long) sb.st_size); 1938471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response(toybuf, NULL) != REQUESTED_PENDINGACTION) TT.c = 0; 1948471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } else TT.c = 0; 1958471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 1968471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 1978471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void transfer_file(int local_fd, int remote_fd) 1988471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 1998471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int len, rfd = (TT.isget)?remote_fd:local_fd, 2008471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma wfd = (TT.isget)?local_fd:remote_fd; 2018471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2028471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (rfd < 0 || wfd < 0) error_exit("Error in file creation:"); 2038471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma while ((len = xread(rfd, toybuf, sizeof(toybuf)))) xwrite(wfd, toybuf, len); 2048471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 2058471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2068471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void get_file(char *l_filename, char *r_filename) 2078471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 2088471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int local_fd = -1, remote_fd; 2098471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2108471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma verify_pasv_mode(r_filename); 2118471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma remote_fd = connect_to_stream(); //Connect to data socket. 2128471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2138471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if local file name will be '-' then local fd will be stdout. 2148471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if ((l_filename[0] == '-') && !l_filename[1]) { 2158471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma local_fd = 1; //file descriptor will become stdout. 2168471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.c = 0; 2178471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } 2188471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2198471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if continue, check for local file existance. 2208471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (TT.c) is_localfile_present(l_filename); 2218471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2228471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //verify the remote file presence. 2238471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response("RETR", r_filename) > FTPFILE_STATUSOKAY) 2248471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma close_stream("RETR"); 2258471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2268471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if local fd is not stdout, create a file descriptor. 2278471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (local_fd == -1) { 2288471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int flags = O_WRONLY; 2298471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2308471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma flags |= (TT.c)? O_APPEND : (O_CREAT | O_TRUNC); 2318471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma local_fd = xcreate((char *)l_filename, flags, 0666); 2328471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } 2338471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma transfer_file(local_fd, remote_fd); 2348471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma xclose(remote_fd); 2358471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma xclose(local_fd); 2368471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response(NULL, NULL) != CLOSE_DATACONECTION) close_stream(NULL); 2378471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma get_ftp_response("QUIT", NULL); 2388471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma toys.exitval = EXIT_SUCCESS; 2398471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 2408471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2418471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmastatic void put_file(char *r_filename, char *l_filename) 2428471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 2438471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma int local_fd = 0, remote_fd; 2448471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma unsigned cmd_status = 0; 2458471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2468471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma verify_pasv_mode(r_filename); 2478471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma remote_fd = connect_to_stream(); //Connect to data socket. 2488471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2498471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //open the local file for transfer. 2508471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if ((l_filename[0] != '-') || l_filename[1]) 2518471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma local_fd = xcreate((char *)l_filename, O_RDONLY, 0666); 2528471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2538471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //verify for the remote file status, Ok or Open: transfer File. 2548471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma cmd_status = get_ftp_response("STOR", r_filename); 2558471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if ( (cmd_status == DATACONNECTION_OPENED) || 2568471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma (cmd_status == FTPFILE_STATUSOKAY)) { 2578471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma transfer_file(local_fd, remote_fd); 2588471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (get_ftp_response(NULL, NULL) != CLOSE_DATACONECTION) close_stream(NULL); 2598471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma get_ftp_response("QUIT", NULL); 2608471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma toys.exitval = EXIT_SUCCESS; 2618471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } else { 2628471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma toys.exitval = EXIT_FAILURE; 2638471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma close_stream("STOR"); 2648471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma } 2658471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma xclose(remote_fd); 2668471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma xclose(local_fd); 2678471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 2688471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2698471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharmavoid ftpget_main(void) 2708471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma{ 2718471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma char **argv = toys.optargs; //host name + file name. 2728471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2738471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.isget = toys.which->name[3] == 'g'; 2748471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.c = 1; 2758471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if user name is not specified. 2768471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (!(toys.optflags & FLAG_u) && (toys.optflags & FLAG_p)) 2778471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma error_exit("Missing username:"); 2788471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if user name and password is not specified in command line. 2798471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (!(toys.optflags & FLAG_u) && !(toys.optflags & FLAG_p)) 2808471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.username = TT.password ="anonymous"; 2818471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2828471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma //if continue is not in the command line argument. 2838471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (TT.isget && !(toys.optflags & FLAG_c)) TT.c = 0; 2848471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2858471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (toys.optflags & FLAG_v) fprintf(stderr, "Connecting to %s\n", argv[0]); 2868471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma get_sockaddr(argv[0]); 2878471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2888471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma TT.sockfp = xfdopen(connect_to_stream(), "r+"); 2898471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma send_requests(); 2908471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma 2918471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma if (TT.isget) get_file(argv[1], argv[2] ? argv[2] : argv[1]); 2928471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma else put_file(argv[1], argv[2] ? argv[2] : argv[1]); 2938471dc08c411822480b2bf622a5ea7fce1cef33dAshwini Sharma} 294