예제 #1
0
static int ftp_receive_head(FILE *control_stream, int *pnFdData, int *pnFileSize, ftp_host_info_t *server,
                            char *server_path, char caFtpHead[FTP_HEAD_SIZE])
{
    printf("ftp_receive_head++++++++++++++++++++++\n");
    char buf[512];
    int rd;

    /* Connect to the data socket */
    if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
        ftp_die("PASV", buf);
    }

    *pnFdData = xconnect_ftpdata(server, buf);
    if (*pnFdData < 0)
        return -1;

    if (ftpcmd("SIZE", server_path, control_stream, buf) == 213) {
        *pnFileSize = strtol(buf + 4, NULL, 10);
        if (*pnFileSize < 0)
            ftp_die("SIZE", buf);
    } else {
        do_continue = 0;
    }

    if (ftpcmd("RETR", server_path, control_stream, buf) > 150) {
        ftp_die("RETR", buf);
    }
    rd = safe_read(*pnFdData, caFtpHead, FTP_HEAD_SIZE);
    printf("ftp_receive_head=============\n");
    return rd;
}
예제 #2
0
static FILE *ftp_login(ftp_host_info_t *server)
{
	FILE *control_stream;
	char buf[512];

	/* Connect to the command socket */
	control_stream = fdopen(xconnect(server->s_in), "r+");
	if (control_stream == NULL) {
		bb_perror_msg_and_die("Couldnt open control stream");
	}

	if (ftpcmd(NULL, NULL, control_stream, buf) != 220) {
		bb_error_msg_and_die("%s", buf + 4);
	}

	/*  Login to the server */
	switch (ftpcmd("USER ", server->user, control_stream, buf)) {
	case 230:
		break;
	case 331:
		if (ftpcmd("PASS ", server->password, control_stream, buf) != 230) {
			bb_error_msg_and_die("PASS error: %s", buf + 4);
		}
		break;
	default:
		bb_error_msg_and_die("USER error: %s", buf + 4);
	}

	ftpcmd("TYPE I", NULL, control_stream, buf);

	return(control_stream);
}
예제 #3
0
파일: ftp.c 프로젝트: dhkim1027/libftp
FILE *ftp_login(ftp_host_info_t *server)
{
	FILE *control_stream;
	char buf[512];
	int conn_ret = -1;

	ftp_fd = lib_create_tcp(__FUNCTION__, 0, 0);
	if(ftp_fd < 0){
		lib_error("[%s] lib_create_tcp err!!", __FUNCTION__);	
		return NULL;
	}

	conn_ret = lib_connect_tcp(__FUNCTION__, ftp_fd, server->ip, server->port);
	if(conn_ret < 0){
		lib_error("[%s] lib_connect_tcp err!!", __FUNCTION__);	
		return NULL;
	}

	/* Connect to the command socket */
	control_stream = fdopen(ftp_fd, "r+");
	if (control_stream == NULL) {
		lib_error("[%s] fdopen err!!", __FUNCTION__);	
		return NULL;
	}

	if (ftpcmd(NULL, NULL, control_stream, buf) != 220) {
		ftp_die(NULL, buf);
	}

	//printf("[%s] debug\n", __FUNCTION__);

	/*  Login to the server */
	switch (ftpcmd("USER", server->user, control_stream, buf)) {
	case 230:
		break;
	case 331:
		if (ftpcmd("PASS", server->password, control_stream, buf) != 230) {
			ftp_die("PASS", buf);
			lib_trace("FTP Login Fail.");
			return NULL;
		}
		else
			lib_trace("FTP Login OK.");
		break;
	default:
		ftp_die("USER", buf);
		lib_trace("FTP Login Fail.");
		return NULL;
	}

	ftpcmd("TYPE I", NULL, control_stream, buf);

	if(ftpcmd("CWD", server->dir, control_stream, buf) != 250){
		ftp_die("CWD", buf);
		return NULL;
	}

	return control_stream;
}
예제 #4
0
static int ftp_send(ftp_host_info_t *server, FILE *control_stream, const char *server_path, char *local_path)
{
    struct stat sbuf;
    char buf[512];
    int fd_data;
    int fd_local;
    int response;

    /*  Connect to the data socket */
    if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
        ftp_die("PASV", buf);
    }
    fd_data = xconnect_ftpdata(server, buf);

    /* get the local file */
    fd_local = STDIN_FILENO;
    if (NOT_LONE_DASH(local_path)) {
        fd_local = xopen(local_path, O_RDONLY, 0666);
        fstat(fd_local, &sbuf);
        sprintf(buf, "ALLO %lu", (long unsigned int)sbuf.st_size);
        response = ftpcmd(buf, NULL, control_stream, buf);
        switch (response) {
        case 200:
        case 202:
            break;
        default:
            close(fd_local);
            ftp_die("ALLO", buf);
            break;
        }
    }

    response = ftpcmd("STOR", server_path, control_stream, buf);
    switch (response) {
    case 125:
    case 150:
        break;
    default:
        close(fd_local);
        ftp_die("STOR", buf);
    }

    /* transfer the file  */
    if (bb_copyfd_eof(fd_local, fd_data) == -1) {
        exit(EXIT_FAILURE);
    }

    /* close it all down */
    close(fd_data);
    if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
        ftp_die("close", buf);
    }
    ftpcmd("QUIT", NULL, control_stream, buf);

    return EXIT_SUCCESS;
}
예제 #5
0
int ftp_recv_to_ram(int nFdData, FILE *control_stream, char caFtpHead[FTP_HEAD_SIZE], int nHeadSize, char *pcRam)
{
    int fd_local = -1;
    char buf[512];
    int status = -1;
    off_t total = 0;
    char buffer[BUFSIZ];
    int size = 0;
    memcpy(pcRam, caFtpHead, nHeadSize);
    total += nHeadSize;

    while (1) {
        ssize_t rd;
        rd = safe_read(nFdData, buffer, BUFSIZ);
        //printf("-----rd =%d----n", rd);
        if (!rd) { /* eof - all done */
            status = 0;
            break;
        }

        if (rd < 0) {
            //bb_error_msg(bb_msg_read_error);
            break;
        }

        memcpy(pcRam + total, buffer, rd);
        total += rd;
        if (status < 0) { /* if we aren't copying till EOF... */
            size -= rd;
            if (!size) {
                /* 'size' bytes copied - all done */
                status = 0;
                break;
            }
        }
    }

    /* close it all down */
    close(nFdData);
    if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
        ftp_die(NULL, buf);
    }
    ftpcmd("QUIT", NULL, control_stream, buf);

    return status ? -1 : total;
}
예제 #6
0
static FILE *ftp_login(ftp_host_info_t *server)
{
    printf("ftp_login++++++++++++++++++++\n");
    FILE *control_stream;
    char buf[512];
    /* Connect to the command socket */
    control_stream = fdopen(xconnect_stream(server->lsa), "r+");
    if (control_stream == NULL) {
        /* fdopen failed - extremely unlikely */
        //bb_error_msg_and_die("ftp login");
        printf("ftp login");
        exit (-1);
    }
    printf("ftp_login++11111111111111111111++++++\n");
    if (ftpcmd(NULL, NULL, control_stream, buf) != 220) {
        printf("ftp_die++\n");
        //ftp_die(NULL, buf);
    }
    printf("ftp_login+++++++2222222222222222222++++\n");
    /*  Login to the server */
    switch (ftpcmd("USER", server->user, control_stream, buf)) {
    case 230:
        printf("ftp_login++++230++++++\n");
        break;
    case 331:
        printf("ftp_login+++++++331++++++++\n");
        if (ftpcmd("PASS", server->password, control_stream, buf) != 230) {
            ftp_die("PASS", buf);
            printf("ftp_login+++ftp_die++++PAS+++++\n");
        }
        break;
    default:
        printf("ftp_login++++++default+++++++\n");
        ftp_die("USER", buf);
    }
    ftpcmd("TYPE I", NULL, control_stream, buf);
    printf("ftp_login==================\n");
    return control_stream;
}
예제 #7
0
static int ftp_send(FILE *control_stream, const char *host, const char *server_path, char *local_path)
{
	struct stat sbuf;
	char buf[512];
	int fd_data;
	int fd_local;
	int response;

	/*  Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		bb_error_msg_and_die("PASV error: %s", buf + 4);
	}
	fd_data = xconnect_ftpdata(host, buf);

	if (ftpcmd("CWD ", server_path, control_stream, buf) != 250) {
		bb_error_msg_and_die("CWD error: %s", buf + 4);
	}

	/* get the local file */
	fd_local = bb_xopen(local_path, O_RDONLY);
	fstat(fd_local, &sbuf);

	sprintf(buf, "ALLO %lu", (unsigned long)sbuf.st_size);
	response = ftpcmd(buf, NULL, control_stream, buf);
	switch (response) {
	case 200:
	case 202:
		break;
	default:
		close(fd_local);
		bb_error_msg_and_die("ALLO error: %s", buf + 4);
		break;
	}

	response = ftpcmd("STOR ", local_path, control_stream, buf);
	switch (response) {
	case 125:
	case 150:
		break;
	default:
		close(fd_local);
		bb_error_msg_and_die("STOR error: %s", buf + 4);
	}

	/* transfer the file  */
	if (bb_copyfd(fd_local, fd_data, 0) == -1) {
		exit(EXIT_FAILURE);
	}

	/* close it all down */
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		bb_error_msg_and_die("error: %s", buf + 4);
	}
	ftpcmd("QUIT", NULL, control_stream, buf);

	return(EXIT_SUCCESS);
}
예제 #8
0
int ftp_recv_to_file(int nFdData, FILE *control_stream, char caFtpHead[FTP_HEAD_SIZE], int nHeadSize, const char *pcLocalFileName)
{
    int fd_local = -1;
    char buf[512];
    int status = -1;
    off_t total = 0;
    char buffer[BUFSIZ];
    int size = 0;
    fd_local = xopen(pcLocalFileName, O_CREAT | O_TRUNC | O_WRONLY, 0666);

    if (fd_local < 0) {
        goto out;
    }

    ssize_t wr = full_write(fd_local, caFtpHead, nHeadSize);
    if (wr < nHeadSize) {
        //bb_error_msg(bb_msg_write_error);
        goto out;
    }

    total += nHeadSize;
    if (!size) {
        size = BUFSIZ;
        status = 1; /* copy until eof */
    }

    while (1) {
        ssize_t rd;
        rd = safe_read(nFdData, buffer, size > BUFSIZ ? BUFSIZ : size);
        //printf("-----rd =%d----n", rd);
        if (!rd) { /* eof - all done */
            status = 0;
            break;
        }

        if (rd < 0) {
            //bb_error_msg(bb_msg_read_error);
            break;
        }

        /* dst_fd == -1 is a fake, else... */
        if (fd_local >= 0) {
            ssize_t wr = full_write(fd_local, buffer, rd);
            if (wr < rd) {
                //bb_error_msg(bb_msg_write_error);
                break;
            }
        }

        total += rd;
        if (status < 0) { /* if we aren't copying till EOF... */
            size -= rd;
            if (!size) {
                /* 'size' bytes copied - all done */
                status = 0;
                break;
            }
        }
    }

    /* close it all down */
    close(fd_local);
    close(nFdData);
    if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
        ftp_die(NULL, buf);
    }
    ftpcmd("QUIT", NULL, control_stream, buf);

out:
    return status ? -1 : total;
}
예제 #9
0
static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, const char *local_path, char *server_path)
{
    char buf[512];
    /* I think 'filesize' usage here is bogus. Let's see... */
    //off_t filesize = -1;
#define filesize ((off_t)-1)
    int fd_data;
    int fd_local = -1;
    off_t beg_range = 0;
    /* Connect to the data socket */
    if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
        ftp_die("PASV", buf);
    }

    fd_data = xconnect_ftpdata(server, buf);
    if (ftpcmd("SIZE", server_path, control_stream, buf) == 213) {
        //filesize = BB_STRTOOFF(buf + 4, NULL, 10);
        //if (errno || filesize < 0)
        //  ftp_die("SIZE", buf);
    } else {
        do_continue = 0;
    }

    if (LONE_DASH(local_path)) {
        fd_local = STDOUT_FILENO;
        do_continue = 0;
    }

    if (do_continue) {
        struct stat sbuf;
        if (lstat(local_path, &sbuf) < 0) {
            //bb_error_msg_and_die("lstat");
            printf("lstat error.");
            exit - 1;
        }
        if (sbuf.st_size > 0) {
            beg_range = sbuf.st_size;
        } else {
            do_continue = 0;
        }
    }

    if (do_continue) {
        sprintf(buf, "REST %""1""d", (int)beg_range);
        if (ftpcmd(buf, NULL, control_stream, buf) != 350) {
            do_continue = 0;
        } else {
            //if (filesize != -1)
            //  filesize -= beg_range;
        }
    }

    if (ftpcmd("RETR", server_path, control_stream, buf) > 150) {
        ftp_die("RETR", buf);
    }

    /* only make a local file if we know that one exists on the remote server */
    if (fd_local == -1) {
        if (do_continue) {
            fd_local = xopen(local_path, O_APPEND | O_WRONLY, 0666);
        } else {
            fd_local = xopen(local_path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
        }
    }

    /* Copy the file */
    if (filesize != -1) {
        if (bb_copyfd_size(fd_data, fd_local, filesize) == -1)
            return EXIT_FAILURE;
    } else {
        if (bb_copyfd_eof(fd_data, fd_local) == -1)
            return EXIT_FAILURE;
    }

    /* close it all down */
    close(fd_data);
    if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
        ftp_die(NULL, buf);
    }
    ftpcmd("QUIT", NULL, control_stream, buf);

    return EXIT_SUCCESS;
}
예제 #10
0
파일: ftp.c 프로젝트: dhkim1027/libftp
int ftp_msend2(ftp_host_info_t *server, FILE *control_stream,
		file_path_t *file_path, int file_cnt)
{
	struct stat sbuf;
	char buf[512];
	int fd_data;
	int* fd_local = NULL;
	int response; 
	int i = 0;

	if(file_cnt == 0)
		return -1;

	fd_local = (int*)malloc(sizeof(int)*file_cnt);
	if(fd_local == NULL){
		lib_error("[%s] malloc err!!", __FUNCTION__);
		return -1;
	}

	for(i=0;i<file_cnt;i++){

		memset(buf, 0, sizeof(buf));

		/*  Connect to the data socket */
		if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
			ftp_die("PASV", buf);
		}

		fd_data = connect_ftpdata(server, buf);
		if(fd_data < 0){
			lib_error("[%s] connect_ftpdata err!!", __FUNCTION__);
			return -1;
		}

		/* get the local file */
		fd_local[i] = STDIN_FILENO;
		if (NOT_LONE_DASH(file_path[i].local_path)) {

			//printf("%d: lc_path : %s, rt_path:%s\n",i, file_path[i].local_path, file_path[i].server_path);
			fd_local[i] = open(file_path[i].local_path, O_RDONLY, 0666);
			if(fd_local[i] < 0){
				lib_error("[%s] open err!!", __FUNCTION__);
				close(fd_data);
				return -1;
			}
			fstat(fd_local[i], &sbuf);

			sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size);
			response = ftpcmd(buf, NULL, control_stream, buf);
			switch (response) {
			case 200:
			case 202:
				break;
			default:
				ftp_die("ALLO", buf);
				break;
			}
		}

		response = ftpcmd("STOR", file_path[i].server_path, control_stream, buf);
		switch (response) {
		case 125:
		case 150:
			break;
		default:
			ftp_die("STOR", buf);
			close(fd_local[i]);
			close(fd_data);
			goto ftp_msend_quit_error;
		}

		/* transfer the file  */
		if (copyfd_eof(fd_local[i], fd_data, 0) == -1) {
			close(fd_data);
			close(fd_local[i]);
			goto ftp_msend_quit_error;
		}

		/* close it all down */
		close(fd_local[i]);

		close(fd_data);
		if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
			ftp_die("close", buf);
		}

	}

	ftpcmd("QUIT", NULL, control_stream, buf);
	return 0;

ftp_msend_quit_error:
	ftpcmd("QUIT", NULL, control_stream, buf);
	return -1;
}
예제 #11
0
static int ftp_send(ftp_host_info_t *server, FILE *control_stream, char *local_path, char *server_path)
{
	int ret = -1;
	off_t filesize = 0;
	struct stat sbuf;
	char buf[512];
	int fd_data = -1;
	int fd_local = -1;
	int response = 0;
	FTP_PARAM ftp_param;

	// Connect to the data socket
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) 
	{
		return -1;
	}

	fd_data = connect_ftpdata(server, buf);
	if (fd_data < 0)
	{
		return -1;
	}
	
	//if (ftpcmd("CWD ", server_path, control_stream, buf) != 250) // [zhb][delete][2006-09-18]
	//改变ftp 工作目录
	ret = getFtpParam(&ftp_param);
	if (ret < 0)
	{
		return -1;
	}

	if (ftpcmd("CWD ", ftp_param.strPath, control_stream, buf) != 250) 
	{
		printf("%s\n", buf);
		close(fd_data);
		return -1;
	}
	
	// get the local file
	if ((local_path[0] == '-') && (local_path[1] == '\0')) 
	{
		fd_local = STDIN_FILENO;
	} 

	else 
	{		
		fd_local = open(local_path, O_RDONLY);
		fstat(fd_local, &sbuf);

		sprintf(buf, "ALLO %lu", (unsigned long)sbuf.st_size);
		filesize = sbuf.st_size;
		response = ftpcmd(buf, NULL, control_stream, buf);
		
		switch (response) 
		{
		case 200:
		case 202:
			break;
		default:
			//close(fd_local); // [zhb][delete][2006-09-18]
			printf("ALLO error(%s)!\n", buf);
			break;
		}
	}
	response = ftpcmd("STOR ", local_path, control_stream, buf);
	switch (response) 
	{
	case 125:
	case 150:
		break;
	default:
		printf("STOR error!\n");
		close(fd_local);		
	}

	// transfer the file
	if ((ret = copyfd_size(fd_local, fd_data, filesize)) == -1) 
	{
		//printf("copyfd_size() Failed!\n");
		return -1;
	}	

	// close it all down
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) 
	{
		printf("ftpcmd(%s) Failed!\n", buf);
		return -1;
	}
	ftpcmd("QUIT", NULL, control_stream, buf);

	return 0;
}
예제 #12
0
static int ftp_recieve(ftp_host_info_t *server, FILE *control_stream, char *local_path, char *server_path)
{
	int ret = -1;
	char buf[512];
	off_t filesize = 0;
	int fd_data = -1;
	int fd_local = -1;
	off_t beg_range = 0;

	/* Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) 
	{
		printf("ftpcmd(PASV) Failed!\n");
		return -1;
	}
	
	fd_data = connect_ftpdata(server, buf);
	if (fd_data == -1)
	{
		printf("connect_ftpdata(%s) Failed!\n", buf);
		return -1;
	}

	if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) 
	{
		unsigned long value=filesize;
		//if (strtoul(buf + 4, &value, 10))
		if (safe_strtoul(buf + 4, &value))
		{			
			close(fd_data);
			return -1;
		}
		filesize = value;
	}

	if ((local_path[0] == '-') && (local_path[1] == '\0')) 
	{
		fd_local = STDOUT_FILENO;
		do_continue = 0;
	}

	if (do_continue) 
	{
		struct stat sbuf;
		if (lstat(local_path, &sbuf) < 0) 
		{
			close(fd_data);
			return -1;
		}
		if (sbuf.st_size > 0) 
		{
			beg_range = sbuf.st_size;
		} 
		else 
		{
			do_continue = 0;
		}
	}

	if (do_continue) 
	{
		sprintf(buf, "REST %ld", (long)beg_range);
		if (ftpcmd(buf, NULL, control_stream, buf) != 350) 
		{
			do_continue = 0;
		} 
		else 
		{
			filesize -= beg_range;
		}
	}

	if (ftpcmd("RETR ", server_path, control_stream, buf) > 150) 
	{
		close(fd_data);
		return -1;
	}
	
	/* only make a local file if we know that one exists on the remote server */
	if (fd_local == -1) 
	{
		if (do_continue) 
		{
			fd_local = open(local_path, O_APPEND | O_WRONLY, 0777);
		} 
		else 
		{
			fd_local = open(local_path, O_CREAT | O_TRUNC | O_WRONLY, 0777);
		}
	}

	if (fd_local < 0)
	{
		close(fd_data);
		return -1;
	}
	
	// Copy the file
	if (copyfd_size(fd_data, fd_local, filesize) == -1) 
	{		
		close(fd_data);
		close(fd_local);
		return -1;
	}	

	// close it all down
	close(fd_data);
	close(fd_local);
	
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) 
	{
		return -1;
	}
	
	ftpcmd("QUIT", NULL, control_stream, buf);

	return 0;
}
예제 #13
0
static FILE *ftp_login(ftp_host_info_t *server)
{
	int ret = -1;
	int socket_fd = -1;
	FILE *control_stream = NULL;
	char buf[512];

	/* Connect to the command socket */
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (socket_fd < 0)
	{
		return NULL;
	}	
	ret = connect(socket_fd, (struct sockaddr *)&server->s_in, sizeof(struct sockaddr_in));
	if (ret < 0)
	{
		// Add the code by lvjh, 2009-04-02
		close(socket_fd);
		
		return NULL;
	}	
	control_stream = fdopen(socket_fd, "r+");
	if (control_stream == NULL) 
	{
		// Add the code by lvjh, 2009-04-02
		close(socket_fd);
		
		return NULL;
	}

	if (ftpcmd(NULL, NULL, control_stream, buf) != 220) 
	{
		// Add the code by lvjh, 2009-04-02
		fclose(control_stream);
		close(socket_fd);
		
		return NULL;
	}

	/*  Login to the server */
	switch (ftpcmd("USER ", server->user, control_stream, buf)) 
	{
	case 230:
		// Add the code by lvjh, 2009-04-02
		fclose(control_stream);
		close(socket_fd);
		
		return NULL;		
		
	case 331:
		if (ftpcmd("PASS ", server->password, control_stream, buf) != 230) 
		{
			// Add the code by lvjh, 2009-04-02
			fclose(control_stream);
			close(socket_fd);
		
			return NULL;
		}
		break;
		
	default:
		// Add the code by lvjh, 2009-04-02
		fclose(control_stream);
		close(socket_fd);
		
		return NULL;		
	}

	ftpcmd("TYPE I", NULL, control_stream, buf);

	// Add the code by lvjh, 2009-04-02
	g_ftp_socket = socket_fd;
		
	return(control_stream);
}
예제 #14
0
static int ftp_recieve(FILE *control_stream, const char *host, const char *local_path, char *server_path)
{
	char *filename;
	char *local_file;
	char buf[512];
	off_t filesize = 0;
	int fd_data;
	int fd_local;
	off_t beg_range = 0;

	filename = bb_get_last_path_component(server_path);
	local_file = concat_path_file(local_path, filename);

	/* Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		bb_error_msg_and_die("PASV error: %s", buf + 4);
	}
	fd_data = xconnect_ftpdata(host, buf);

	if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) {
		filesize = atol(buf + 4);
	}

	if (do_continue) {
		struct stat sbuf;
		if (lstat(local_file, &sbuf) < 0) {
			bb_perror_msg_and_die("fstat()");
		}
		if (sbuf.st_size > 0) {
			beg_range = sbuf.st_size;
		} else {
			do_continue = 0;
		}
	}

	if (do_continue) {
		sprintf(buf, "REST %ld", (long)beg_range);
		if (ftpcmd(buf, NULL, control_stream, buf) != 350) {
			do_continue = 0;
		} else {
			filesize -= beg_range;
		}
	}

	if (ftpcmd("RETR ", server_path, control_stream, buf) > 150) {
		bb_error_msg_and_die("RETR error: %s", buf + 4);
	}

	/* only make a local file if we know that one exists on the remote server */
	if (do_continue) {
		fd_local = bb_xopen(local_file, O_APPEND | O_WRONLY);
	} else {
		fd_local = bb_xopen(local_file, O_CREAT | O_TRUNC | O_WRONLY);
	}

	/* Copy the file */
	if (bb_copyfd(fd_data, fd_local, filesize) == -1) {
		exit(EXIT_FAILURE);
	}

	/* close it all down */
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		bb_error_msg_and_die("ftp error: %s", buf + 4);
	}
	ftpcmd("QUIT", NULL, control_stream, buf);
	
	return(EXIT_SUCCESS);
}
예제 #15
0
static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa)
{
    char buf[512];
    FILE *sfp;
    char *str;
    int port;

    if (!target->user)
        target->user = xstrdup("anonymous:busybox@");

    sfp = open_socket(lsa);
    if (ftpcmd(NULL, NULL, sfp, buf) != 220)
        bb_error_msg_and_die("%s", sanitize_string(buf+4));

    /*
     * Splitting username:password pair,
     * trying to log in
     */
    str = strchr(target->user, ':');
    if (str)
        *str++ = '\0';
    switch (ftpcmd("USER ", target->user, sfp, buf)) {
    case 230:
        break;
    case 331:
        if (ftpcmd("PASS ", str, sfp, buf) == 230)
            break;
    /* fall through (failed login) */
    default:
        bb_error_msg_and_die("ftp login: %s", sanitize_string(buf+4));
    }

    ftpcmd("TYPE I", NULL, sfp, buf);

    /*
     * Querying file size
     */
    if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) {
        G.content_len = BB_STRTOOFF(buf+4, NULL, 10);
        if (G.content_len < 0 || errno) {
            bb_error_msg_and_die("SIZE value is garbage");
        }
        G.got_clen = 1;
    }

    /*
     * Entering passive mode
     */
    if (ftpcmd("PASV", NULL, sfp, buf) != 227) {
pasv_error:
        bb_error_msg_and_die("bad response to %s: %s", "PASV", sanitize_string(buf));
    }
    // Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage]
    // Server's IP is N1.N2.N3.N4 (we ignore it)
    // Server's port for data connection is P1*256+P2
    str = strrchr(buf, ')');
    if (str) str[0] = '\0';
    str = strrchr(buf, ',');
    if (!str) goto pasv_error;
    port = xatou_range(str+1, 0, 255);
    *str = '\0';
    str = strrchr(buf, ',');
    if (!str) goto pasv_error;
    port += xatou_range(str+1, 0, 255) * 256;
    set_nport(lsa, htons(port));

    *dfpp = open_socket(lsa);

    if (G.beg_range) {
        sprintf(buf, "REST %"OFF_FMT"u", G.beg_range);
        if (ftpcmd(buf, NULL, sfp, buf) == 350)
            G.content_len -= G.beg_range;
    }

    if (ftpcmd("RETR ", target->path, sfp, buf) > 150)
        bb_error_msg_and_die("bad response to %s: %s", "RETR", sanitize_string(buf));

    return sfp;
}
예제 #16
0
int wget_main(int argc UNUSED_PARAM, char **argv)
{
    char buf[512];
    struct host_info server, target;
    len_and_sockaddr *lsa;
    unsigned opt;
    int redir_limit;
    char *proxy = NULL;
    char *dir_prefix = NULL;
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
    char *post_data;
    char *extra_headers = NULL;
    llist_t *headers_llist = NULL;
#endif
    FILE *sfp;                      /* socket to web/ftp server         */
    FILE *dfp;                      /* socket to ftp server (data)      */
    char *fname_out;                /* where to direct output (-O)      */
    int output_fd = -1;
    bool use_proxy;                 /* Use proxies if env vars are set  */
    const char *proxy_flag = "on";  /* Use proxies if env vars are set  */
    const char *user_agent = "Wget";/* "User-Agent" header field        */

    static const char keywords[] ALIGN1 =
        "content-length\0""transfer-encoding\0""chunked\0""location\0";
    enum {
        KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location
    };
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
    static const char wget_longopts[] ALIGN1 =
        /* name, has_arg, val */
        "continue\0"         No_argument       "c"
        "spider\0"           No_argument       "s"
        "quiet\0"            No_argument       "q"
        "output-document\0"  Required_argument "O"
        "directory-prefix\0" Required_argument "P"
        "proxy\0"            Required_argument "Y"
        "user-agent\0"       Required_argument "U"
        /* Ignored: */
        // "tries\0"            Required_argument "t"
        // "timeout\0"          Required_argument "T"
        /* Ignored (we always use PASV): */
        "passive-ftp\0"      No_argument       "\xff"
        "header\0"           Required_argument "\xfe"
        "post-data\0"        Required_argument "\xfd"
        /* Ignored (we don't do ssl) */
        "no-check-certificate\0" No_argument   "\xfc"
        ;
#endif

    INIT_G();

#if ENABLE_FEATURE_WGET_LONG_OPTIONS
    applet_long_options = wget_longopts;
#endif
    /* server.allocated = target.allocated = NULL; */
    opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
    opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:",
                   &fname_out, &dir_prefix,
                   &proxy_flag, &user_agent,
                   NULL, /* -t RETRIES */
                   NULL /* -T NETWORK_READ_TIMEOUT */
                   IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
                   IF_FEATURE_WGET_LONG_OPTIONS(, &post_data)
                  );
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
    if (headers_llist) {
        int size = 1;
        char *cp;
        llist_t *ll = headers_llist;
        while (ll) {
            size += strlen(ll->data) + 2;
            ll = ll->link;
        }
        extra_headers = cp = xmalloc(size);
        while (headers_llist) {
            cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist));
        }
    }
#endif

    /* TODO: compat issue: should handle "wget URL1 URL2..." */

    target.user = NULL;
    parse_url(argv[optind], &target);

    /* Use the proxy if necessary */
    use_proxy = (strcmp(proxy_flag, "off") != 0);
    if (use_proxy) {
        proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy");
        if (proxy && proxy[0]) {
            server.user = NULL;
            parse_url(proxy, &server);
        } else {
            use_proxy = 0;
        }
    }
    if (!use_proxy) {
        server.port = target.port;
        if (ENABLE_FEATURE_IPV6) {
            server.host = xstrdup(target.host);
        } else {
            server.host = target.host;
        }
    }

    if (ENABLE_FEATURE_IPV6)
        strip_ipv6_scope_id(target.host);

    /* Guess an output filename, if there was no -O FILE */
    if (!(opt & WGET_OPT_OUTNAME)) {
        fname_out = bb_get_last_path_component_nostrip(target.path);
        /* handle "wget http://kernel.org//" */
        if (fname_out[0] == '/' || !fname_out[0])
            fname_out = (char*)"index.html";
        /* -P DIR is considered only if there was no -O FILE */
        if (dir_prefix)
            fname_out = concat_path_file(dir_prefix, fname_out);
    } else {
        if (LONE_DASH(fname_out)) {
            /* -O - */
            output_fd = 1;
            opt &= ~WGET_OPT_CONTINUE;
        }
    }
#if ENABLE_FEATURE_WGET_STATUSBAR
    G.curfile = bb_get_last_path_component_nostrip(fname_out);
#endif

    /* Impossible?
    if ((opt & WGET_OPT_CONTINUE) && !fname_out)
    	bb_error_msg_and_die("can't specify continue (-c) without a filename (-O)");
    */

    /* Determine where to start transfer */
    if (opt & WGET_OPT_CONTINUE) {
        output_fd = open(fname_out, O_WRONLY);
        if (output_fd >= 0) {
            G.beg_range = xlseek(output_fd, 0, SEEK_END);
        }
        /* File doesn't exist. We do not create file here yet.
         * We are not sure it exists on remove side */
    }

    redir_limit = 5;
resolve_lsa:
    lsa = xhost2sockaddr(server.host, server.port);
    if (!(opt & WGET_OPT_QUIET)) {
        char *s = xmalloc_sockaddr2dotted(&lsa->u.sa);
        fprintf(stderr, "Connecting to %s (%s)\n", server.host, s);
        free(s);
    }
establish_session:
    if (use_proxy || !target.is_ftp) {
        /*
         *  HTTP session
         */
        char *str;
        int status;

        /* Open socket to http server */
        sfp = open_socket(lsa);

        /* Send HTTP request */
        if (use_proxy) {
            fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",
                    target.is_ftp ? "f" : "ht", target.host,
                    target.path);
        } else {
            if (opt & WGET_OPT_POST_DATA)
                fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path);
            else
                fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
        }

        fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
                target.host, user_agent);

#if ENABLE_FEATURE_WGET_AUTHENTICATION
        if (target.user) {
            fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
                    base64enc_512(buf, target.user));
        }
        if (use_proxy && server.user) {
            fprintf(sfp, "Proxy-Authorization: Basic %s\r\n",
                    base64enc_512(buf, server.user));
        }
#endif

        if (G.beg_range)
            fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
        if (extra_headers)
            fputs(extra_headers, sfp);

        if (opt & WGET_OPT_POST_DATA) {
            char *estr = URL_escape(post_data);
            fprintf(sfp, "Content-Type: application/x-www-form-urlencoded\r\n");
            fprintf(sfp, "Content-Length: %u\r\n" "\r\n" "%s",
                    (int) strlen(estr), estr);
            /*fprintf(sfp, "Connection: Keep-Alive\r\n\r\n");*/
            /*fprintf(sfp, "%s\r\n", estr);*/
            free(estr);
        } else
#endif
        {   /* If "Connection:" is needed, document why */
            fprintf(sfp, /* "Connection: close\r\n" */ "\r\n");
        }

        /*
         * Retrieve HTTP response line and check for "200" status code.
         */
read_response:
        if (fgets(buf, sizeof(buf), sfp) == NULL)
            bb_error_msg_and_die("no response from server");

        str = buf;
        str = skip_non_whitespace(str);
        str = skip_whitespace(str);
        // FIXME: no error check
        // xatou wouldn't work: "200 OK"
        status = atoi(str);
        switch (status) {
        case 0:
        case 100:
            while (gethdr(buf, sizeof(buf), sfp /*, &n*/) != NULL)
                /* eat all remaining headers */;
            goto read_response;
        case 200:
        /*
        Response 204 doesn't say "null file", it says "metadata
        has changed but data didn't":

        "10.2.5 204 No Content
        The server has fulfilled the request but does not need to return
        an entity-body, and might want to return updated metainformation.
        The response MAY include new or updated metainformation in the form
        of entity-headers, which if present SHOULD be associated with
        the requested variant.

        If the client is a user agent, it SHOULD NOT change its document
        view from that which caused the request to be sent. This response
        is primarily intended to allow input for actions to take place
        without causing a change to the user agent's active document view,
        although any new or updated metainformation SHOULD be applied
        to the document currently in the user agent's active view.

        The 204 response MUST NOT include a message-body, and thus
        is always terminated by the first empty line after the header fields."

        However, in real world it was observed that some web servers
        (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero.
        */
        case 204:
            break;
        case 300:	/* redirection */
        case 301:
        case 302:
        case 303:
            break;
        case 206:
            if (G.beg_range)
                break;
        /* fall through */
        default:
            bb_error_msg_and_die("server returned error: %s", sanitize_string(buf));
        }

        /*
         * Retrieve HTTP headers.
         */
        while ((str = gethdr(buf, sizeof(buf), sfp /*, &n*/)) != NULL) {
            /* gethdr converted "FOO:" string to lowercase */
            smalluint key;
            /* strip trailing whitespace */
            char *s = strchrnul(str, '\0') - 1;
            while (s >= str && (*s == ' ' || *s == '\t')) {
                *s = '\0';
                s--;
            }
            key = index_in_strings(keywords, buf) + 1;
            if (key == KEY_content_length) {
                G.content_len = BB_STRTOOFF(str, NULL, 10);
                if (G.content_len < 0 || errno) {
                    bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str));
                }
                G.got_clen = 1;
                continue;
            }
            if (key == KEY_transfer_encoding) {
                if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)
                    bb_error_msg_and_die("transfer encoding '%s' is not supported", sanitize_string(str));
                G.chunked = G.got_clen = 1;
            }
            if (key == KEY_location && status >= 300) {
                if (--redir_limit == 0)
                    bb_error_msg_and_die("too many redirections");
                fclose(sfp);
                G.got_clen = 0;
                G.chunked = 0;
                if (str[0] == '/')
                    /* free(target.allocated); */
                    target.path = /* target.allocated = */ xstrdup(str+1);
                /* lsa stays the same: it's on the same server */
                else {
                    parse_url(str, &target);
                    if (!use_proxy) {
                        server.host = target.host;
                        /* strip_ipv6_scope_id(target.host); - no! */
                        /* we assume remote never gives us IPv6 addr with scope id */
                        server.port = target.port;
                        free(lsa);
                        goto resolve_lsa;
                    } /* else: lsa stays the same: we use proxy */
                }
                goto establish_session;
            }
        }
//		if (status >= 300)
//			bb_error_msg_and_die("bad redirection (no Location: header from server)");

        /* For HTTP, data is pumped over the same connection */
        dfp = sfp;

    } else {
        /*
         *  FTP session
         */
        sfp = prepare_ftp_session(&dfp, &target, lsa);
    }

    if (opt & WGET_OPT_SPIDER) {
        if (ENABLE_FEATURE_CLEAN_UP)
            fclose(sfp);
        return EXIT_SUCCESS;
    }

    if (output_fd < 0) {
        int o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL;
        /* compat with wget: -O FILE can overwrite */
        if (opt & WGET_OPT_OUTNAME)
            o_flags = O_WRONLY | O_CREAT | O_TRUNC;
        output_fd = xopen(fname_out, o_flags);
    }

    retrieve_file_data(dfp, output_fd);
    xclose(output_fd);

    if (dfp != sfp) {
        /* It's ftp. Close it properly */
        fclose(dfp);
        if (ftpcmd(NULL, NULL, sfp, buf) != 226)
            bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4));
        /* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */
    }

    return EXIT_SUCCESS;
}
예제 #17
0
static int ftp_send_ext(ftp_host_info_t *server, FILE *control_stream, char *local_path, char *local_data, unsigned long data_size, char *server_path)
{
	int ret = -1;
	char buf[512];
	int fd_data = -1;
	int response = 0;
	FTP_PARAM ftp_param;

	// Connect to the data socket
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) 
	{
		return -1;
	}

	fd_data = connect_ftpdata(server, buf);
	if (fd_data < 0)
	{
		return -1;
	}

	//printf("Entry ftp_send_ext function ftp_param.strPath = %s\n", ftp_param.strPath);
	//if (ftpcmd("CWD ", server_path, control_stream, buf) != 250) // [zhb][delete][2006-09-18]
	#if 1
	//改变ftp 工作目录
	ret = getFtpParam(&ftp_param);
	if (ret < 0)
	{
		return -1;
	}

#if 1
	if (ftpcmd("MKD ", ftp_param.strPath, control_stream, buf) != 250) 
	{
		printf("%s\n", buf);
		//close(fd_data);
		//return -1;
	}
#endif

	if (ftpcmd("CWD ", ftp_param.strPath, control_stream, buf) != 250) 
	{
		printf("%s\n", buf);
		close(fd_data);
		return -1;
	}
	#endif

	#if 0
	if (ftpcmd("CWD ", "./", control_stream, buf) != 250) 
	{
		printf("%s\n", buf);
		close(fd_data);
		return -1;
	}
	#endif
	
	
	
	// get the local file
	sprintf(buf, "ALLO %lu", (unsigned long)data_size);
	response = ftpcmd(buf, NULL, control_stream, buf);	
	switch (response) 
	{
	case 200:
	case 202:
		break;
	default:
		printf("ALLO error(%s)!\n", buf);
		break;
	}
	
	response = ftpcmd("STOR ", local_path, control_stream, buf);
	switch (response) 
	{
	case 125:
	case 150:
		break;
	default:
		printf("STOR error!\n");
	}

	// transfer the file
	if ((ret = copyfd_size_ext(local_data, fd_data, data_size)) == -1) 
	{
		//printf("copyfd_size_ext() Failed!\n");
		// Add the code by lvjh, 2009-04-02
		close(fd_data);
		
		return -1;
	}	

	// close it all down
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) 
	{
		printf("ftpcmd(%s) Failed!\n", buf);
		return -1;
	}
	ftpcmd("QUIT", NULL, control_stream, buf);

	return 0;
}
예제 #18
0
static int ftp_recieve(ftp_host_info_t *server, FILE *control_stream,
		const char *local_path, char *server_path)
{
	char buf[512];
	off_t filesize = 0;
	int fd_data;
	int fd_local = -1;
	off_t beg_range = 0;

	/* Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		bb_error_msg_and_die("PASV error: %s", buf + 4);
	}
	fd_data = xconnect_ftpdata(server, buf);

	if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) {
		unsigned long value=filesize;
		if (safe_strtoul(buf + 4, &value))
			bb_error_msg_and_die("SIZE error: %s", buf + 4);
		filesize = value;
	}

	if ((local_path[0] == '-') && (local_path[1] == '\0')) {
		fd_local = STDOUT_FILENO;
		do_continue = 0;
	}

	if (do_continue) {
		struct stat sbuf;
		if (lstat(local_path, &sbuf) < 0) {
			bb_perror_msg_and_die("fstat()");
		}
		if (sbuf.st_size > 0) {
			beg_range = sbuf.st_size;
		} else {
			do_continue = 0;
		}
	}

	if (do_continue) {
		sprintf(buf, "REST %ld", (long)beg_range);
		if (ftpcmd(buf, NULL, control_stream, buf) != 350) {
			do_continue = 0;
		} else {
			filesize -= beg_range;
		}
	}

	if (ftpcmd("RETR ", server_path, control_stream, buf) > 150) {
		bb_error_msg_and_die("RETR error: %s", buf + 4);
	}

	/* only make a local file if we know that one exists on the remote server */
	if (fd_local == -1) {
		if (do_continue) {
			fd_local = bb_xopen(local_path, O_APPEND | O_WRONLY);
		} else {
			fd_local = bb_xopen(local_path, O_CREAT | O_TRUNC | O_WRONLY);
		}
	}

	/* Copy the file */
	if (bb_copyfd_size(fd_data, fd_local, filesize) == -1) {
		exit(EXIT_FAILURE);
	}

	/* close it all down */
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		bb_error_msg_and_die("ftp error: %s", buf + 4);
	}
	ftpcmd("QUIT", NULL, control_stream, buf);

	return(EXIT_SUCCESS);
}
예제 #19
0
파일: ftp.c 프로젝트: dhkim1027/libftp
int ftp_send(ftp_host_info_t *server, FILE *control_stream,
		const char *server_path, char *local_path)
{
	struct stat sbuf;
	char buf[512];
	int fd_data;
	int fd_local;
	int response; 
	
	/*  Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		ftp_die("PASV", buf);
	}

	fd_data = connect_ftpdata(server, buf);
	if(fd_data < 0){
		lib_error("[%s] connect_ftpdata err!!", __FUNCTION__);
		return -1;
	}

	/* get the local file */
	fd_local = STDIN_FILENO;
	if (NOT_LONE_DASH(local_path)) {
		fd_local = open(local_path, O_RDONLY, 0666);
		if(fd_local < 0){
			lib_error("[%s] open err!!", __FUNCTION__);
			close(fd_data);
			return -1;
		}
		fstat(fd_local, &sbuf);

		sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size);
		response = ftpcmd(buf, NULL, control_stream, buf);
		switch (response) {
		case 200:
		case 202:
			break;
		default:
			ftp_die("ALLO", buf);
			break;
		}
	}
	response = ftpcmd("STOR", server_path, control_stream, buf);
	switch (response) {
	case 125:
	case 150:
		break;
	default:
		ftp_die("STOR", buf);
		close(fd_local);
		close(fd_data);
		return -1;

	}

	/* transfer the file  */
	if (copyfd_eof(fd_local, fd_data, 0) == -1) {
		close(fd_data);
		close(fd_local);
		return -1;
	}

	/* close it all down */
	close(fd_local);
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		ftp_die("close", buf);
	}
	//ftpcmd("NOOP", NULL, control_stream, buf);
	ftpcmd("QUIT", NULL, control_stream, buf);

	return 0;
}