コード例 #1
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
static inline ssize_t
tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size)
{
    struct gnutella_socket *s = ptr;
    ssize_t ret;
    int saved_errno;

    socket_check(s);
    g_assert(is_valid_fd(s->file_desc));

    ret = s_read(s->file_desc, buf, size);
    saved_errno = errno;
    tls_signal_pending(s);
    if ((ssize_t) -1 == ret) {
        tls_set_errno(s, saved_errno);
        if (!is_temporary_error(saved_errno)) {
            socket_connection_reset(s);
        }
    } else if (0 == ret) {
        socket_eof(s);
    }
    tls_transport_debug("tls_pull", s, size, ret);
    errno = saved_errno;
    return ret;
}
コード例 #2
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
int
tls_init(struct gnutella_socket *s)
{
    socket_check(s);
    g_assert_not_reached();
    return -1;
}
コード例 #3
0
ファイル: sexyz.c プロジェクト: ftnapps/pkg-sbbs
BOOL data_waiting(void* unused, unsigned timeout)
{
	BOOL rd;

	if(!socket_check(sock,&rd,NULL,timeout))
		return(FALSE);
	return(rd);
}
コード例 #4
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_write(lua_State *L)
{
  lua_apr_socket *object = socket_check(L, 1, 1);
  int nresults = write_buffer(L, &object->output);
  apr_status_t status = flush_buffer(L, &object->output, 1);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);
  return nresults;
}
コード例 #5
0
asmlinkage int solaris_socket(int family, int type, int protocol)
{
    int (*sys_socket)(int, int, int) =
        (int (*)(int, int, int))SYS(socket);

    type = socket_check (family, type);
    if (type < 0) return type;
    return sys_socket(family, type, protocol);
}
コード例 #6
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_gc(lua_State *L)
{
  lua_apr_socket *socket = socket_check(L, 1, 0);
  if (object_collectable((lua_apr_refobj*)socket)) {
    free_buffer(L, &socket->input.buffer);
    free_buffer(L, &socket->output.buffer);
    socket_close_impl(L, socket);
  }
  release_object((lua_apr_refobj*)socket);
  return 0;
}
コード例 #7
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_tostring(lua_State *L)
{
  lua_apr_socket *socket;

  socket = socket_check(L, 1, 0);
  if (socket->handle != NULL)
    lua_pushfstring(L, "%s (%p)", lua_apr_socket_type.friendlyname, socket->handle);
  else
    lua_pushfstring(L, "%s (closed)", lua_apr_socket_type.friendlyname);

  return 1;
}
コード例 #8
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
void
tls_wio_link(struct gnutella_socket *s)
{
    socket_check(s);

    s->wio.write = tls_write;
    s->wio.read = tls_read;
    s->wio.writev = tls_writev;
    s->wio.readv = tls_readv;
    s->wio.sendto = tls_no_sendto;
    s->wio.flush = tls_flush;
}
コード例 #9
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_opt_set(lua_State *L)
{
  apr_status_t status;
  lua_apr_socket *object;
  apr_int32_t option, value;

  object = socket_check(L, 1, 1);
  option = option_check(L, 2);
  value = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : luaL_checkinteger(L, 3);
  status = apr_socket_opt_set(object->handle, option, value);
  return push_status(L, status);
}
コード例 #10
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
int socket_fd_set(lua_State *L)
{
  lua_apr_socket *object;
  apr_status_t status;
  apr_os_sock_t fd;

  object = socket_check(L, 1, 0);
  fd = luaL_checkinteger(L, 2);
  status = apr_os_sock_put(&object->handle, &fd, object->pool);

  return push_status(L, status);
}
コード例 #11
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_listen(lua_State *L)
{
  lua_apr_socket *object;
  apr_status_t status;
  apr_int32_t backlog = SOMAXCONN;

  object = socket_check(L, 1, 1);
  if (strcmp(lua_tostring(L, 2), "max") != 0)
    backlog = luaL_checkinteger(L, 2);
  status = apr_socket_listen(object->handle, backlog);

  return push_status(L, status);
}
コード例 #12
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
int socket_fd_get(lua_State *L)
{
  apr_status_t status;
  lua_apr_socket *object;
  apr_os_sock_t fd;

  object = socket_check(L, 1, 1);
  status = apr_os_sock_get(&fd, object->handle);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);

  lua_pushinteger(L, fd);
  return 1;
}
コード例 #13
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_timeout_set(lua_State *L)
{
  lua_apr_socket *object;
  apr_status_t status;
  apr_interval_time_t timeout;

  object = socket_check(L, 1, 1);
  if (lua_isnumber(L, 2))
    timeout = luaL_checkinteger(L, 2);
  else
    timeout = lua_toboolean(L, 2) ? -1 : 0;
  status = apr_socket_timeout_set(object->handle, timeout);

  return push_status(L, status);
}
コード例 #14
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_recvfrom(lua_State *L)
{
  lua_apr_socket *object;
  apr_status_t status;
  apr_sockaddr_t address = { 0 };
  apr_size_t buflen;
  apr_int32_t flags;
  char buffer[1024], ip_addr[APRMAXHOSTLEN];
  char *bufptr;
  int i;

  /* Validate arguments. */
  object = socket_check(L, 1, 1);
  buflen = luaL_optint(L, 2, sizeof buffer);

  /* Use dynamically allocated buffer only when necessary. */
  bufptr = (buflen > sizeof buffer) ? lua_newuserdata(L, buflen) : &buffer[0];

  flags = 0;
  status = apr_socket_recvfrom(&address, object->handle, flags, bufptr, &buflen);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);

  /* Convert the socket address to a Lua table. */
  lua_newtable(L);

  /* Get the IP address in numeric format. */
  status = apr_sockaddr_ip_getbuf(ip_addr, sizeof ip_addr, &address);
  if (status == APR_SUCCESS)
    lua_pushstring(L, ip_addr), lua_setfield(L, -2, "address");

  /* Get the port number. */
  lua_pushnumber(L, address.port), lua_setfield(L, -2, "port");

  /* Get the address family. */
  for (i = 0; i < count(family_values); i++)
    if (family_values[i] == address.family) {
      lua_pushstring(L, family_options[i]);
      lua_setfield(L, -2, "family");
      break;
    }

  /* Push the received data. */
  lua_pushlstring(L, bufptr, buflen);

  /* Return address table and received data. */
  return 2;
}
コード例 #15
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_shutdown(lua_State *L)
{
  const char *options[] = { "read", "write", "both", NULL };
  const apr_shutdown_how_e values[] = {
    APR_SHUTDOWN_READ, APR_SHUTDOWN_WRITE, APR_SHUTDOWN_READWRITE
  };
  lua_apr_socket *socket;
  apr_status_t status;
  apr_shutdown_how_e how;

  socket = socket_check(L, 1, 1);
  how = values[luaL_checkoption(L, 2, NULL, options)];
  status = apr_socket_shutdown(socket->handle, how);

  return push_status(L, status);
}
コード例 #16
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_opt_get(lua_State *L)
{
  apr_status_t status;
  lua_apr_socket *object;
  apr_int32_t option, value;

  object = socket_check(L, 1, 1);
  option = option_check(L, 2);
  status = apr_socket_opt_get(object->handle, option, &value);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);
  else if (option == APR_SO_SNDBUF || option == APR_SO_RCVBUF)
    lua_pushinteger(L, value);
  else
    lua_pushboolean(L, value);
  return 1;
}
コード例 #17
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_accept(lua_State *L)
{
  lua_apr_socket *server, *client = NULL;
  apr_status_t status;

  server = socket_check(L, 1, 1);
  status = socket_alloc(L, &client);
  client->family = server->family;
  client->protocol = server->protocol;
  if (status == APR_SUCCESS)
    status = apr_socket_accept(&client->handle, server->handle, client->pool);
  socket_init(L, client);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);

  return 1;
}
コード例 #18
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_connect(lua_State *L)
{
  lua_apr_socket *object;
  apr_sockaddr_t *address;
  const char *host;
  apr_port_t port;
  apr_status_t status;

  object = socket_check(L, 1, 1);
  host = luaL_checkstring(L, 2);
  port = luaL_checkinteger(L, 3);
  status = apr_sockaddr_info_get(&address, host, object->family, port, 0, object->pool);
  if (status == APR_SUCCESS)
    status = apr_socket_connect(object->handle, address);

  return push_status(L, status);
}
コード例 #19
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_timeout_get(lua_State *L)
{
  lua_apr_socket *object;
  apr_status_t status;
  apr_interval_time_t timeout;

  object = socket_check(L, 1, 1);
  status = apr_socket_timeout_get(object->handle, &timeout);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);
  else if (timeout <= 0)
    lua_pushboolean(L, timeout != 0);
  else
    lua_pushinteger(L, (lua_Integer) timeout);

  return 1;
}
コード例 #20
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
static int
tls_flush(struct wrap_io *wio)
{
    struct gnutella_socket *s = wio->ctx;

    socket_check(s);

    if (s->tls.snarf) {
        if (GNET_PROPERTY(tls_debug > 1)) {
            g_debug("tls_flush: snarf=%zu host=%s fd=%d",
                    s->tls.snarf,
                    host_addr_port_to_string(s->addr, s->port), s->file_desc);
        }
        (void ) tls_write_intern(wio, NULL, 0);
        if (s->tls.snarf)
            return -1;
    }
    return 0;
}
コード例 #21
0
ファイル: mainapp.cpp プロジェクト: hughhugh/ardupilot-rov
/*
  main program
 */
int main(int argc, const char *argv[])
{
    sock.set_broadcast();

    printf("Starting DSP code\n");
    send_storage();
        
    ardupilot_start();
    while (true) {
        uint64_t now = micros64();
        if (now - last_get_storage_us > 1000*1000) {
            printf("tick t=%.6f\n", now*1.0e-6f);
            ardupilot_heartbeat();
            get_storage();
            last_get_storage_us = now;
        }
        socket_check();
        usleep(5000);
    }
}
コード例 #22
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
static ssize_t
tls_write(struct wrap_io *wio, const void *buf, size_t size)
{
    struct gnutella_socket *s = wio->ctx;
    ssize_t ret;

    socket_check(s);
    g_assert(socket_uses_tls(s));
    g_assert(NULL != buf);
    g_assert(size_is_positive(size));

    ret = tls_flush(wio);
    if (0 == ret) {
        ret = tls_write_intern(wio, buf, size);
        if (s->gdk_tag) {
            tls_socket_evt_change(s, INPUT_EVENT_WX);
        }
    }
    g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
    tls_signal_pending(s);
    return ret;
}
コード例 #23
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
void
tls_free(struct gnutella_socket *s)
{
    tls_context_t ctx;

    socket_check(s);
    ctx = s->tls.ctx;
    if (ctx) {
        if (ctx->session) {
            gnutls_deinit(ctx->session);
        }
        if (ctx->server_cred) {
            gnutls_anon_free_server_credentials(ctx->server_cred);
            ctx->server_cred = NULL;
        }
        if (ctx->client_cred) {
            gnutls_anon_free_client_credentials(ctx->client_cred);
            ctx->client_cred = NULL;
        }
        WFREE(ctx);
        s->tls.ctx = NULL;
    }
}
コード例 #24
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
static inline ssize_t
tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size)
{
    struct gnutella_socket *s = ptr;
    ssize_t ret;
    int saved_errno;

    socket_check(s);
    g_assert(is_valid_fd(s->file_desc));

    ret = s_write(s->file_desc, buf, size);
    saved_errno = errno;
    tls_signal_pending(s);
    if ((ssize_t) -1 == ret) {
        tls_set_errno(s, saved_errno);
        if (ECONNRESET == saved_errno || EPIPE == saved_errno) {
            socket_connection_reset(s);
        }
    }
    tls_transport_debug("tls_push", s, size, ret);
    errno = saved_errno;
    return ret;
}
コード例 #25
0
ファイル: io_net.c プロジェクト: LuaDist/lua-apr
static int socket_addr_get(lua_State *L)
{
  const char *options[] = { "local", "remote", NULL };
  const apr_interface_e values[] = { APR_LOCAL, APR_REMOTE };
  lua_apr_socket *object;
  apr_sockaddr_t *address;
  apr_status_t status;
  apr_interface_e which;
  char *ip_address;

  object = socket_check(L, 1, 1);
  which = values[luaL_checkoption(L, 2, "remote", options)];
  status = apr_socket_addr_get(&address, which, object->handle);
  if (status == APR_SUCCESS)
    status = apr_sockaddr_ip_get(&ip_address, address);
  if (status != APR_SUCCESS)
    return push_error_status(L, status);
  lua_pushstring(L, ip_address);
  lua_pushinteger(L, address->port);
  lua_pushstring(L, address->hostname);

  return 3;
}
コード例 #26
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
void
tls_bye(struct gnutella_socket *s)
{
    int ret;

    socket_check(s);
    g_return_if_fail(s->tls.ctx);
    g_return_if_fail(s->tls.ctx->session);

    if ((SOCK_F_EOF | SOCK_F_SHUTDOWN) & s->flags)
        return;

    if (tls_flush(&s->wio) && GNET_PROPERTY(tls_debug)) {
        g_warning("%s(): tls_flush(fd=%d) failed", G_STRFUNC, s->file_desc);
    }

    ret = gnutls_bye(s->tls.ctx->session,
                     SOCK_CONN_INCOMING != s->direction
                     ? GNUTLS_SHUT_WR : GNUTLS_SHUT_RDWR);

    if (ret < 0) {
        switch (ret) {
        case GNUTLS_E_INTERRUPTED:
        case GNUTLS_E_AGAIN:
            break;
        case GNUTLS_E_PULL_ERROR:
        case GNUTLS_E_PUSH_ERROR:
            /* Logging already done by tls_transport_debug() */
            break;
        default:
            if (GNET_PROPERTY(tls_debug)) {
                g_carp("gnutls_bye() failed: host=%s error=%m",
                       host_addr_port_to_string(s->addr, s->port));
            }
        }
    }
}
コード例 #27
0
ファイル: tls_common.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Change the monitoring condition on the socket.
 */
static void
tls_socket_evt_change(struct gnutella_socket *s, inputevt_cond_t cond)
{
    socket_check(s);
    g_assert(socket_with_tls(s));	/* No USES yet, may not have handshaked */
    g_assert(INPUT_EVENT_EXCEPTION != cond);

    if (0 == s->gdk_tag)
        return;

    if (cond != s->tls.cb_cond) {
        int saved_errno = errno;

        if (GNET_PROPERTY(tls_debug) > 1) {
            int fd = socket_evt_fd(s);
            g_debug("tls_socket_evt_change: fd=%d, cond=%s -> %s",
                    fd, inputevt_cond_to_string(s->tls.cb_cond),
                    inputevt_cond_to_string(cond));
        }
        inputevt_remove(&s->gdk_tag);
        socket_evt_set(s, cond, s->tls.cb_handler, s->tls.cb_data);
        errno = saved_errno;
    }
}
コード例 #28
0
ファイル: execnet.cpp プロジェクト: K6BSD/SBBSUnstable
bool sbbs_t::ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest)
{
	char		cmd[512];
	char		rsp[512];
	char		path[MAX_PATH+1];
	char		buf[4097];
	int			rd;
	int			result;
	ulong		total=0;
	SOCKET		data_sock;
	union xp_sockaddr	addr;
	socklen_t	addr_len;
	FILE*		fp=NULL;
	bool		error=false;
	struct timeval	tv;
	fd_set			socket_set;

	SAFECOPY(path,src);

	if(!fexistcase(path))
		return(false);

	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET) {
		bprintf("ftp: failure, line %d",__LINE__);
		return(false);
	}

	if(csi->ftp_mode&CS_FTP_PASV) {

#if 0	// Debug
		bprintf("Connecting to %s:%hd\r\n"
			,inet_ntoa(addr.in.sin_addr)
			,ntohs(addr.in.sin_port));
#endif

		if(connect(data_sock,&addr.addr,sizeof(addr.in))!=0) {
			bprintf("ftp: failure, line %d",__LINE__);
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(false);
		}
	}

	if((fp=fopen(path,"rb"))==NULL) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	sprintf(cmd,"STOR %s",dest);

	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=150 /* Open data connection */) {
		bprintf("ftp: failure, line %d",__LINE__);
		close_socket(data_sock);
		return(false);
	}

	if(!(csi->ftp_mode&CS_FTP_PASV)) {	/* Normal (Active) FTP */

		/* Setup for select() */
		tv.tv_sec=TIMEOUT_SOCK_LISTEN;
		tv.tv_usec=0;

		FD_ZERO(&socket_set);
		FD_SET(data_sock,&socket_set);

		result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
		if(result<1) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		SOCKET accept_sock;

		addr_len=sizeof(addr);
		if((accept_sock=accept_socket(data_sock,&addr,&addr_len))
			==INVALID_SOCKET) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		close_socket(data_sock);
		data_sock=accept_sock;
	}

	while(online && !feof(fp)) {

		rd=fread(buf,sizeof(char),sizeof(buf),fp);
		if(rd<1) /* EOF or READ error */
			break;

		if(!socket_check(ctrl_sock,NULL,NULL,0))
			break; /* Control connection lost */

		if(sendsocket(data_sock,buf,rd)<1) {
			error=true;
			break;
		}

		total+=rd;
		
		if(csi->ftp_mode&CS_FTP_HASH)
			outchar('#');
	}

	if(csi->ftp_mode&CS_FTP_HASH) {
		CRLF;
	}

	fclose(fp);

	close_socket(data_sock);

	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
		|| atoi(rsp)!=226 /* Upload complete */)
		return(false);

	if(!error)
		bprintf("ftp: %lu bytes sent.\r\n", total);

	return(!error);
}
コード例 #29
0
ファイル: execnet.cpp プロジェクト: K6BSD/SBBSUnstable
bool sbbs_t::ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir)
{
	char		cmd[512];
	char		rsp[512];
	char		buf[4097];
	int			rd;
	int			result;
	BOOL		data_avail;
	ulong		total=0;
	SOCKET		data_sock;
	union xp_sockaddr	addr;
	socklen_t	addr_len;
	FILE*		fp=NULL;
	struct timeval	tv;
	fd_set			socket_set;

	if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET)
		return(false);

	if(csi->ftp_mode&CS_FTP_PASV) {

#if 0	// Debug
		bprintf("Connecting to %s:%hd\r\n"
			,inet_ntoa(addr.in.sin_addr)
			,ntohs(addr.in.sin_port));
#endif

		/* TODO: IPv6 */
		if(connect(data_sock,&addr.addr,sizeof(SOCKADDR_IN))!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(false);
		}
	}

	if(dir)
		sprintf(cmd,"LIST %s",src);
	else
		sprintf(cmd,"RETR %s",src);

	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=150 /* Open data connection */) {
		close_socket(data_sock);
		return(false);
	}

	if(!(csi->ftp_mode&CS_FTP_PASV)) {	/* Normal (Active) FTP */

		/* Setup for select() */
		tv.tv_sec=TIMEOUT_SOCK_LISTEN;
		tv.tv_usec=0;

		FD_ZERO(&socket_set);
		FD_SET(data_sock,&socket_set);

		result=select(data_sock+1,&socket_set,NULL,NULL,&tv);
		if(result<1) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		SOCKET accept_sock;

		addr_len=sizeof(addr);
		if((accept_sock=accept_socket(data_sock,&addr,&addr_len))
			==INVALID_SOCKET) {
			csi->socket_error=ERROR_VALUE;
			closesocket(data_sock);
			return(false);
		}

		close_socket(data_sock);
		data_sock=accept_sock;
	}

	if(!dir)
		if((fp=fopen(dest,"wb"))==NULL) {
			close_socket(data_sock);
			return(false);
		}

	while(online) {

		if(!socket_check(ctrl_sock,NULL,NULL,0))
			break; /* Control connection lost */

		if(!socket_check(data_sock,&data_avail,NULL,100))
			break; /* Data connection lost */

		if(!data_avail)
			continue;
	
		if((rd=recv(data_sock, buf, sizeof(buf)-1, 0))<1)
			break;

		if(dir) {
			buf[rd]=0;
			bputs(buf);
		} else
			fwrite(buf,1,rd,fp);

		total+=rd;
		
		if(!dir && csi->ftp_mode&CS_FTP_HASH)
			outchar('#');
	}

	if(!dir && csi->ftp_mode&CS_FTP_HASH) {
		CRLF;
	}

	if(fp!=NULL)
		fclose(fp);

	close_socket(data_sock);

	if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) 
		|| atoi(rsp)!=226 /* Download complete */)
		return(false);

	bprintf("ftp: %lu bytes received.\r\n", total);

	return(true);
}
コード例 #30
0
ファイル: execnet.cpp プロジェクト: K6BSD/SBBSUnstable
/* FTP Command/Response function */
bool sbbs_t::ftp_cmd(csi_t* csi, SOCKET sock, const char* cmdsrc, char* rsp)
{
	char	cmd[512];
	int		len;
	BOOL	data_avail;
	time_t	start;

	if(cmdsrc!=NULL) {
		sprintf(cmd,"%s\r\n",cmdsrc);

		if(csi->ftp_mode&CS_FTP_ECHO_CMD)
			bputs(cmd);

		len=strlen(cmd);
		if(sendsocket(sock,cmd,len)!=len) {
			csi->socket_error=ERROR_VALUE;
			return(FALSE);
		}
	}

	if(rsp!=NULL) {

		int		rd;
		char	ch;

		while(1) {
			rd=0;

			start=time(NULL);
			while(rd<500) {

				if(!online)
					return(FALSE);

				if(!socket_check(sock,&data_avail,NULL,1000))
					return(FALSE);

				if(!data_avail) {
					if(time(NULL)-start>TIMEOUT_FTP_RESPONSE) {
						lprintf(LOG_WARNING,"!ftp_cmd: TIMEOUT_FTP_RESPONSE (%d) exceeded"
							,TIMEOUT_FTP_RESPONSE);
						return(FALSE);
					}
					continue;
				}

				if(recv(sock, &ch, 1, 0)!=1) {
					csi->socket_error=ERROR_VALUE;
					return(FALSE);
				}

				if(ch=='\n' && rd>=1) 
					break;

				rsp[rd++]=ch;
			}
			rsp[rd-1]=0;
			if(csi->ftp_mode&CS_FTP_ECHO_RSP)
				bprintf("%s\r\n",rsp);
			if(rsp[0]!=' ' && rsp[3]!='-')
				break;
		}
	}		

	return(TRUE);
}