Ejemplo n.º 1
0
int
ftp_get(ftpbuf_t *ftp, FILE *outfp, const char *path, ftptype_t type)
{
	databuf_t		*data = NULL;
	char			*ptr;
	int			lastch;
	int			rcvd;

	if (ftp == NULL)
		return 0;

	if (!ftp_type(ftp, type))
		goto bail;

	if ((data = ftp_getdata(ftp)) == NULL)
		goto bail;

	if (!ftp_putcmd(ftp, "RETR", path))
		goto bail;
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125))
		goto bail;

	if ((data = data_accept(data)) == NULL)
		goto bail;

	lastch = 0;
	while ((rcvd = my_recv(data->fd, data->buf, FTP_BUFSIZE))) {
		if (rcvd == -1)
			goto bail;

		if (type == FTPTYPE_ASCII) {
			for (ptr = data->buf; rcvd; rcvd--, ptr++) {
				if (lastch == '\r' && *ptr != '\n')
					putc('\r', outfp);
				if (*ptr != '\r')
					putc(*ptr, outfp);
				lastch = *ptr;
			}
		}
		else {
			fwrite(data->buf, rcvd, 1, outfp);
		}
	}

	if (type == FTPTYPE_ASCII && lastch == '\r')
		putc('\r', outfp);

	data = data_close(data);

	if (ferror(outfp))
		goto bail;

	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250))
		goto bail;

	return 1;
bail:
	data_close(data);
	return 0;
}
Ejemplo n.º 2
0
unsigned long long ftp_filesize(const char *path)
{
    unsigned long long ret;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_filesize(path);
#endif

    if(!ftp->has_size_command)
        return -1;
    if(ftp_type(tmBinary) != 0)
        return -1;
    ftp_set_tmp_verbosity(vbError);
    ftp_cmd("SIZE %s", path);
    if(ftp->fullcode == 502) {
        ftp->has_size_command = false;
        return -1;
    }
    if(ftp->code == ctComplete) {
        sscanf(ftp->reply, "%*s %llu", &ret);
        return ret;
    }
    return -1;
}
Ejemplo n.º 3
0
static int ftp_init_receive(const char *path, transfer_mode_t mode,
							ftp_transfer_func hookf)
{
	long rp = ftp->restart_offset;
	char *e;

	ftp->restart_offset = 0L;

	foo_hookf = hookf;
	reset_transfer_info();

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

	ftp_cmd("RETR %s", path);
	if(ftp->code != ctPrelim)
		return -1;

	if(!sock_accept(ftp->data, "r", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	/* try to get the total file size */
	{
		/* see if we have cached this directory/file */
		rfile *f = ftp_cache_get_file(path);
		if(f)
			ftp->ti.total_size = f->size;
		else {
			/* try to figure out file size from RETR reply
			 * Opening BINARY mode data connection for foo.mp3 (14429793 bytes)
			 *                                                  ^^^^^^^^ aha!
			 *
			 * note: this might not be the _total_ filesize if we are RESTarting
			 */
			e = strstr(ftp->reply, " bytes");
			if(e != 0) {
				while((e > ftp->reply) && isdigit((int)e[-1]))
					e--;
				ftp->ti.total_size = strtoul(e,NULL,10);
			} /* else we don't bother */
		}
	}
	return 0;
}
Ejemplo n.º 4
0
/* {{{ ftp_nb_get
 */
int
ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_t path_len, ftptype_t type, zend_long resumepos)
{
	databuf_t		*data = NULL;
	char			arg[11];

	if (ftp == NULL) {
		return PHP_FTP_FAILED;
	}

	if (!ftp_type(ftp, type)) {
		goto bail;
	}

	if ((data = ftp_getdata(ftp)) == NULL) {
		goto bail;
	}

	if (resumepos>0) {
		int arg_len = snprintf(arg, sizeof(arg), ZEND_LONG_FMT, resumepos);

		if (arg_len < 0) {
			goto bail;
		}
		if (!ftp_putcmd(ftp, "REST", sizeof("REST")-1, arg, arg_len)) {
			goto bail;
		}
		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {
			goto bail;
		}
	}

	if (!ftp_putcmd(ftp, "RETR", sizeof("RETR")-1, path, path_len)) {
		goto bail;
	}
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
		goto bail;
	}

	if ((data = data_accept(data, ftp)) == NULL) {
		goto bail;
	}

	ftp->data = data;
	ftp->stream = outstream;
	ftp->lastch = 0;
	ftp->nb = 1;

	return (ftp_nb_continue_read(ftp));

bail:
	ftp->data = data_close(ftp, data);
	return PHP_FTP_FAILED;
}
Ejemplo n.º 5
0
/* {{{ ftp_size
 */
zend_long
ftp_size(ftpbuf_t *ftp, const char *path)
{
	if (ftp == NULL) {
		return -1;
	}
	if (!ftp_type(ftp, FTPTYPE_IMAGE)) {
		return -1;
	}
	if (!ftp_putcmd(ftp, "SIZE", path)) {
		return -1;
	}
	if (!ftp_getresp(ftp) || ftp->resp != 213) {
		return -1;
	}
	return atol(ftp->inbuf);
}
Ejemplo n.º 6
0
/* {{{ ftp_nb_put
 */
int
ftp_nb_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, zend_long startpos)
{
	databuf_t		*data = NULL;
	char			arg[11];

	if (ftp == NULL) {
		return 0;
	}
	if (!ftp_type(ftp, type)) {
		goto bail;
	}
	if ((data = ftp_getdata(ftp)) == NULL) {
		goto bail;
	}
	if (startpos > 0) {
		snprintf(arg, sizeof(arg), ZEND_LONG_FMT, startpos);
		if (!ftp_putcmd(ftp, "REST", arg)) {
			goto bail;
		}
		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {
			goto bail;
		}
	}

	if (!ftp_putcmd(ftp, "STOR", path)) {
		goto bail;
	}
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
		goto bail;
	}
	if ((data = data_accept(data, ftp)) == NULL) { 
		goto bail;
	}
	ftp->data = data;
	ftp->stream = instream;
	ftp->lastch = 0;
	ftp->nb = 1;

	return (ftp_nb_continue_write(ftp));

bail:
	ftp->data = data_close(ftp, data);
	return PHP_FTP_FAILED;
}
Ejemplo n.º 7
0
int ftp_list(const char *cmd, const char *param, FILE *fp)
{
  if (!cmd || !fp || !ftp_connected())
    return -1;

#ifdef HAVE_LIBSSH
  if (ftp->session)
    return ssh_list(cmd, param, fp);
#endif

  reset_transfer_info();
  foo_hookf = NULL;

#if 0 /* don't care about transfer type, binary should work well... */
  ftp_type(tmAscii);
#endif

  if (ftp_init_transfer() != 0) {
    ftp_err(_("transfer initialization failed"));
    return -1;
  }

  ftp_set_tmp_verbosity(vbNone);
  if (param)
    ftp_cmd("%s %s", cmd, param);
  else
    ftp_cmd("%s", cmd);
  if (ftp->code != ctPrelim)
    return -1;

  if (!sock_accept(ftp->data, "r", ftp_is_passive())) {
    perror("accept()");
    return -1;
  }

  if (FILE_recv_ascii(ftp->data, fp) != 0)
    return -1;

  sock_destroy(ftp->data);
  ftp->data = NULL;

  ftp_read_reply();

  return ftp->code == ctComplete ? 0 : -1;
}
Ejemplo n.º 8
0
Archivo: handles.c Proyecto: yuyuvn/ftp
/**
 * Generates response message for client
 * @param cmd Current command
 * @param state Current connection state
 */
void response(Command *cmd, State *state)
{
  switch(lookup_cmd(cmd->command)){
    case USER: ftp_user(cmd,state); break;
    case PASS: ftp_pass(cmd,state); break;
    case PASV: ftp_pasv(cmd,state); break;
    case LIST: ftp_list(cmd,state); break;
    case CWD:  ftp_cwd(cmd,state); break;
    case PWD:  ftp_pwd(cmd,state); break;
    case MKD:  ftp_mkd(cmd,state); break;
    case RMD:  ftp_rmd(cmd,state); break;
    case RETR: ftp_retr(cmd,state); break;
    case STOR: ftp_stor(cmd,state); break;
    case DELE: ftp_dele(cmd,state); break;
    case SIZE: ftp_size(cmd,state); break;
    case ABOR: ftp_abor(state); break;
    case QUIT: ftp_quit(state); break;
    case TYPE: ftp_type(cmd,state); break;
    case CDUP: ftp_cdup(state); break;
    case HELP: ftp_help(cmd, state); break;
    case NLST: ftp_nlst(cmd, state); break;
    case RNFR: ftp_rnfr(cmd, state); break;
    case RNTO: ftp_rnto(cmd, state); break;
    case APPE: ftp_appe(cmd, state); break;
    case NOOP:
      if(state->logged_in){
        state->message = "200 Zzz...\n";
      }else{
        state->message = "530 Please login with USER and PASS\n";
      }
      write_state(state);
      break;
    default: 
      state->message = "500 Unknown command\n";
      write_state(state);
      break;
  }
}
Ejemplo n.º 9
0
/* {{{ ftp_put
 */
int
ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, zend_long startpos)
{
	databuf_t		*data = NULL;
	zend_long			size;
	char			*ptr;
	int			ch;
	char			arg[11];

	if (ftp == NULL) {
		return 0;
	}
	if (!ftp_type(ftp, type)) {
		goto bail;
	}
	if ((data = ftp_getdata(ftp)) == NULL) {
		goto bail;
	}
	ftp->data = data;	

	if (startpos > 0) {
		snprintf(arg, sizeof(arg), ZEND_LONG_FMT, startpos);
		if (!ftp_putcmd(ftp, "REST", arg)) {
			goto bail;
		}
		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {
			goto bail;
		}
	}

	if (!ftp_putcmd(ftp, "STOR", path)) {
		goto bail;
	}
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
		goto bail;
	}
	if ((data = data_accept(data, ftp)) == NULL) {
		goto bail;
	}

	size = 0;
	ptr = data->buf;
	while (!php_stream_eof(instream) && (ch = php_stream_getc(instream))!=EOF) {
		/* flush if necessary */
		if (FTP_BUFSIZE - size < 2) {
			if (my_send(ftp, data->fd, data->buf, size) != size) {
				goto bail;
			}
			ptr = data->buf;
			size = 0;
		}

		if (ch == '\n' && type == FTPTYPE_ASCII) {
			*ptr++ = '\r';
			size++;
		}

		*ptr++ = ch;
		size++;
	}

	if (size && my_send(ftp, data->fd, data->buf, size) != size) {
		goto bail;
	}
	ftp->data = data = data_close(ftp, data);

	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250 && ftp->resp != 200)) {
		goto bail;
	}
	return 1;
bail:
	ftp->data = data_close(ftp, data);
	return 0;
}
Ejemplo n.º 10
0
/* {{{ ftp_get
 */
int
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, zend_long resumepos)
{
	databuf_t		*data = NULL;
	size_t			rcvd;
	char			arg[11];

	if (ftp == NULL) {
		return 0;
	}
	if (!ftp_type(ftp, type)) {
		goto bail;
	}

	if ((data = ftp_getdata(ftp)) == NULL) {
		goto bail;
	}
	
	ftp->data = data;

	if (resumepos > 0) {
		snprintf(arg, sizeof(arg), ZEND_LONG_FMT, resumepos);
		if (!ftp_putcmd(ftp, "REST", arg)) {
			goto bail;
		}
		if (!ftp_getresp(ftp) || (ftp->resp != 350)) {
			goto bail;
		}
	}

	if (!ftp_putcmd(ftp, "RETR", path)) {
		goto bail;
	}
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) {
		goto bail;
	}

	if ((data = data_accept(data, ftp)) == NULL) {
		goto bail;
	}

	while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
		if (rcvd == -1) {
			goto bail;
		}

		if (type == FTPTYPE_ASCII) {
#ifndef PHP_WIN32
			char *s;
#endif
			char *ptr = data->buf;
			char *e = ptr + rcvd;
			/* logic depends on the OS EOL
			 * Win32 -> \r\n
			 * Everything Else \n
			 */
#ifdef PHP_WIN32
			php_stream_write(outstream, ptr, (e - ptr));
			ptr = e;
#else
			while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) {
				php_stream_write(outstream, ptr, (s - ptr));
				if (*(s + 1) == '\n') {
					s++;
					php_stream_putc(outstream, '\n');
				}
				ptr = s + 1;
			}
#endif
			if (ptr < e) {
				php_stream_write(outstream, ptr, (e - ptr));
			}
		} else if (rcvd != php_stream_write(outstream, data->buf, rcvd)) {
			goto bail;
		}
	}

	ftp->data = data = data_close(ftp, data);

	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) {
		goto bail;
	}

	return 1;
bail:
	ftp->data = data_close(ftp, data);
	return 0;
}
Ejemplo n.º 11
0
/* transfers SRCFILE on SRCFTP to DESTFILE on DESTFTP
 * using pasv mode on SRCFTP and port mode on DESTFTP
 *
 */
int ftp_fxpfile(Ftp *srcftp, const char *srcfile,
				Ftp *destftp, const char *destfile,
				fxpmode_t how, transfer_mode_t mode)
{
	int r;
	unsigned int old_reply_timeout;
	Ftp *thisftp;
	unsigned char addr[6];

/*	printf("FxP: %s -> %s\n", srcftp->url->hostname, destftp->url->hostname);*/

	if(srcftp == destftp) {
		ftp_err(_("FxP between same hosts\n"));
		return -1;
	}

#ifdef HAVE_LIBSSH
	if(ftp->session) {
		ftp_err("FxP with SSH not implemented\n");
		return -1;
	}
#endif

	thisftp = ftp; /* save currently active connection */

	/* setup source side */
	ftp_use(srcftp);
	ftp_type(mode);
  // TODO: IPv6 support
	if(!ftp_pasv(false, addr, NULL)) {
		ftp_use(thisftp);
		return -1;
	}
	ftp->ti.total_size = -1;

	/* setup destination side */
	ftp_use(destftp);
	ftp_type(mode);
	ftp_cmd("PORT %d,%d,%d,%d,%d,%d",
			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
	if(ftp->code != ctComplete) {
		ftp_use(thisftp);
		return -1;
	}
	ftp->ti.total_size = -1;

	ftp_use(destftp);

	if(how == fxpResume) {
		rfile *f;

		f = ftp_get_file(destfile);
		if(f && f->size != (unsigned long long)-1)
			ftp->restart_offset = f->size;
		else {
			ftp->restart_offset = ftp_filesize(destfile);
			if(ftp->restart_offset == (unsigned long long)-1) {
				ftp_err(_("unable to get remote filesize of '%s',"
						  " unable to resume\n"),
						destfile);
				ftp->restart_offset = 0L;
			}
		}
	} else
		ftp->restart_offset = 0L;

	if(ftp->restart_offset) {
		/* RESTart on destftp */
		ftp_cmd("REST %ld", ftp->restart_offset);
		if(ftp->code != ctContinue)
			return -1;
		ftp_use(srcftp);
		ftp_cmd("REST %ld", ftp->restart_offset);
		if(ftp->code != ctContinue)
			return -1;
	}

	/* issue a STOR command on DESTFTP */
	ftp_use(destftp);
	switch(how) {
	case fxpUnique:
		if(ftp->has_stou_command) {
			ftp_cmd("STOU %s", destfile);
			if(ftp->fullcode == 502)
				ftp->has_stou_command = false;
		} else {
			ftp->code = ctError;
			ftp->fullcode = 502;
		}
		break;
	case fxpAppend:
		ftp_cmd("APPE %s", destfile);
		break;
	case fxpNormal:
	default:
		ftp_cmd("STOR %s", destfile);
		break;
	}

	ftp_cache_flush_mark_for(destfile);

	if(ftp->code != ctPrelim) {
		ftp_use(thisftp);
		return -1;
	}

	/* issue a RETR command on SRCFTP */
	ftp_use(srcftp);
	ftp_cmd("RETR %s", srcfile);
	if(ftp->code != ctPrelim) {
		ftp_use(destftp);
		ftp_abort(NULL);
		ftp_use(thisftp);
		return -1;
	}

	ftp_use(destftp);
	old_reply_timeout = ftp->reply_timeout;
	ftp_reply_timeout(0);
	ftp_read_reply();
	ftp_reply_timeout(old_reply_timeout);

	r = (ftp->code == ctComplete ? 0 : -1);

	ftp_use(srcftp);
	old_reply_timeout = ftp->reply_timeout;
	ftp_reply_timeout(0);
	ftp_read_reply();
	ftp_reply_timeout(old_reply_timeout);

	ftp_use(thisftp);

	return r;
}
Ejemplo n.º 12
0
static int ftp_send(const char *path, FILE *fp, putmode_t how,
					transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long rp = ftp->restart_offset;
	ftp->restart_offset = 0L;

	if(how == putUnique && !ftp->has_stou_command)
		return -1;

  if (how == putTryUnique && !ftp->has_stou_command)
    how = putNormal;

	reset_transfer_info();
	ftp->ti.transfer_is_put = true;

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

  ftp_set_tmp_verbosity(vbError);
  switch (how) {
  case putAppend:
    ftp_cmd("APPE %s", path);
    break;

  case putTryUnique:
  case putUnique:
    ftp_cmd("STOU %s", path);
    if (ftp->fullcode == 502 || ftp->fullcode == 504) {
      ftp->has_stou_command = false;
      if (how == putTryUnique)
        how = putNormal;
      else
        break;
    }
    else
      break;

  default:
    ftp_cmd("STOR %s", path);
    break;
  }

	if(ftp->code != ctPrelim)
		return -1;

	if(how == putUnique) {
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
	}

	if(!sock_accept(ftp->data, "w", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	ftp_cache_flush_mark_for(path);

	if(mode == tmBinary)
		r = FILE_send_binary(fp, ftp->data);
	else
		r = FILE_send_ascii(fp, ftp->data);
	sock_flush(ftp->data);
	sock_destroy(ftp->data);
	ftp->data = 0;

	if(r == 0) {
		transfer_finished();
		ftp_read_reply();
		ftp->ti.ioerror = (ftp->code != ctComplete);
		if(ftp->code != ctComplete) {
			ftp_trace("transfer failed\n");
			return -1;
		}
	} else
		transfer_finished();

	return 0;
}
Ejemplo n.º 13
0
/**
* 作用: 从本地复制文件到服务器 STOR
* 参数: SOCKET,源地址,目的地址,文件大小
* 返回值: 0 表示列表成功  result>0 表示其他错误响应码
*         -1:文件创建失败  -2 pasv接口错误
* */
int ftp_local2server(SOCKET c_sock, char* s, char* d, int* size)
{
	SOCKET d_sock;
	ssize_t len, send_len;
	char buf[BUFSIZ];
	FILE *fp;
	int send_re;
	int result;
	// 打开本地文件
	fp = fopen(s, "rb");
	if (NULL == fp)
	{
		logger.error("从本地复制文件到服务器 can't open the file.");
		return -1;
	}
	// 设置传输模式
	ftp_type(c_sock, 'I');
	// 连接到PASV接口
	d_sock = ftp_pasv_connect(c_sock);
	if (d_sock == -1)
	{
		fclose(fp);
		return -1;
	}

	// 发送STOR命令
	memset(buf, sizeof(buf), 0);
	sprintf(buf, "STOR %s\r\n", d);
	send_re = ftp_sendcmd(c_sock, buf);
	if (send_re >= 300 || send_re == 0)
	{
		fclose(fp);
		return send_re;
	}

	// 开始向PASV通道写数据
	memset(buf, sizeof(buf), 0);
	while ((len = fread(buf, 1, BUFSIZ, fp)) > 0)
	{
		send_len = send(d_sock, buf, len, 0);
		if (send_len != len)
		{
			closesocket(d_sock);
			fclose(fp);
			return -1;
		}
		if (NULL != size)
		{
			*size += send_len;
		}
	}
	// 完成上传
	closesocket(d_sock);
	fclose(fp);

	// 向服务器接收响应码
	memset(buf, sizeof(buf), 0);
	len = recv(c_sock, buf, BUFSIZ, 0);
	buf[len] = 0;
	sscanf(buf, "%d", &result);
	if (result >= 300)
	{
		return result;
	}
	return 0;
}
Ejemplo n.º 14
0
/**
* 作用: 从服务器复制文件到本地 RETR
* 参数: SOCKET,源地址,目的地址,文件大小
* 返回值: 0 表示列表成功  result>0 表示其他错误响应码
*         -1:文件创建失败  -2 pasv接口错误
* */
int ftp_server2local(SOCKET c_sock, char *s, char* d, int* size)
{
	SOCKET d_sock;
	ssize_t len, write_len;
	char buf[BUFSIZ];
	int result;
	*size = 0;

	// 打开本地文件
	FILE* fp = fopen(d, "wb");
	if (NULL == fp)
	{
		logger.error("从服务器复制文件到本地 can't open the file.");
		return -1;
	}
	// 设置传输模式
	ftp_type(c_sock, 'I');

	// 连接到PASV接口,用于传输文件
	d_sock = ftp_pasv_connect(c_sock);
	if (d_sock == -1)
	{
		fclose(fp); // 关闭文件
		return -2;
	}

	// 发送RETR命令
	memset(buf, sizeof(buf), 0);
	sprintf(buf, "RETR %s\r\n", s);
	result = ftp_sendcmd(c_sock, buf);
	// 150 Opening data channel for file download from server of "xxxx"
	if (result >= 300 || result == 0) // 失败可能是没有权限什么的,具体看响应码
	{
		fclose(fp);
		return result;
	}

	// 开始向PASV读取数据(下载)
	memset(buf, sizeof(buf), 0);
	while ((len = recv(d_sock, buf, BUFSIZ, 0)) > 0)
	{
		write_len = fwrite(&buf, len, 1, fp);
		if (write_len != 1) // 写入文件不完整
		{
			closesocket(d_sock); // 关闭套接字
			fclose(fp); // 关闭文件
			return -1;
		}
		if (NULL != size)
		{
			*size += write_len;
		}
	}
	// 下载完成
	closesocket(d_sock);
	fclose(fp);

	// 向服务器接收返回值
	memset(buf, sizeof(buf), 0);
	len = recv(c_sock, buf, BUFSIZ, 0);
	buf[len] = 0;
	sscanf(buf, "%d", &result);
	if (result >= 300)
	{
		return result;
	}
	//226 Successfully transferred "xxxx"
	return 0;
}
Ejemplo n.º 15
0
int
ftp_put(ftpbuf_t *ftp, const char *path, FILE *infp, ftptype_t type)
{
	databuf_t		*data = NULL;
	int			size;
	char			*ptr;
	int			ch;

	if (ftp == NULL)
		return 0;

	if (!ftp_type(ftp, type))
		goto bail;

	if ((data = ftp_getdata(ftp)) == NULL)
		goto bail;

	if (!ftp_putcmd(ftp, "STOR", path))
		goto bail;
	if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125))
		goto bail;

	if ((data = data_accept(data)) == NULL)
		goto bail;

	size = 0;
	ptr = data->buf;
	while ((ch = getc(infp)) != EOF) {
		/* flush if necessary */
		if (FTP_BUFSIZE - size < 2) {
			if (my_send(data->fd, data->buf, size) != size)
				goto bail;
			ptr = data->buf;
			size = 0;
		}

		if (ch == '\n' && type == FTPTYPE_ASCII) {
			*ptr++ = '\r';
			size++;
		}

		*ptr++ = ch;
		size++;
	}

	if (size && my_send(data->fd, data->buf, size) != size)
		goto bail;

	if (ferror(infp))
		goto bail;

	data = data_close(data);

	if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250))
		goto bail;

	return 1;
bail:
	data_close(data);
	return 0;
}