示例#1
0
static int
soc_close(struct _reent *r,
          int           fd)
{
	Handle sockfd = *(Handle*)fd;

	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();

	cmdbuf[0] = IPC_MakeHeader(0xB,1,2); // 0xB0042
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = IPC_Desc_CurProcessHandle();

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		errno = SYNC_ERROR;
		return ret;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret =_net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		errno = -ret;
		return -1;
	}

	return 0;
}
示例#2
0
int socListen(int sockfd, int max_connections)
{
    Result ret = 0;
    u32 *cmdbuf = getThreadCommandBuffer();

    cmdbuf[0] = IPC_MakeHeader(0x3,2,2); // 0x30082
    cmdbuf[1] = (u32)sockfd;
    cmdbuf[2] = (u32)max_connections;
    cmdbuf[3] = IPC_Desc_CurProcessHandle();

    ret = svcSendSyncRequest(SOCU_handle);
    if(ret != 0)
    {
        //errno = SYNC_ERROR;
        return ret;
    }

    ret = (int)cmdbuf[1];
    if(ret == 0)
        ret = _net_convert_error(cmdbuf[2]);

    if(ret < 0) {
        //errno = -ret;
        return -1;
    }

    return 0;
}
示例#3
0
int socSetsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
{
    int ret = 0;
    u32 *cmdbuf = getThreadCommandBuffer();

    cmdbuf[0] = IPC_MakeHeader(0x12,4,4); // 0x120104
    cmdbuf[1] = (u32)sockfd;
    cmdbuf[2] = (u32)level;
    cmdbuf[3] = (u32)optname;
    cmdbuf[4] = (u32)optlen;
    cmdbuf[5] = IPC_Desc_CurProcessHandle();
    cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
    cmdbuf[8] = (u32)optval;

    ret = svcSendSyncRequest(SOCU_handle);
    if(ret != 0) {
        return ret;
    }

    ret = (int)cmdbuf[1];
    if(ret == 0)
        ret = _net_convert_error(cmdbuf[2]);

    if(ret < 0) {
        //errno = -ret;
        return -1;
    }

    return ret;
}
示例#4
0
int sockatmark(int sockfd)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();

	sockfd = soc_get_fd(sockfd);
	if(sockfd < 0) {
		errno = -sockfd;
		return -1;
	}

	cmdbuf[0] = IPC_MakeHeader(0x15,1,2); // 0x150042
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = IPC_Desc_CurProcessHandle();

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		errno = SYNC_ERROR;
		return -1;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		errno = -ret;
		return -1;
	}

	return ret;
}
示例#5
0
ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();	
	u32 tmp_addrlen = 0;
	u8 tmpaddr[0x1c];
	u32 saved_threadstorage[4];

	if(src_addr)
		tmp_addrlen = 0x1c;

	memset(tmpaddr, 0, 0x1c);

	cmdbuf[0] = 0x00080102;
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = (u32)len;
	cmdbuf[3] = (u32)flags;
	cmdbuf[4] = (u32)tmp_addrlen;
	cmdbuf[5] = 0x20;

	saved_threadstorage[0] = cmdbuf[0x100>>2];
	saved_threadstorage[1] = cmdbuf[0x104>>2];
	saved_threadstorage[2] = cmdbuf[0x108>>2];
	saved_threadstorage[3] = cmdbuf[0x10c>>2];
	
	cmdbuf[0x100>>2] = (((u32)len)<<14) | 2;
	cmdbuf[0x104>>2] = (u32)buf;
	cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
	cmdbuf[0x10c>>2] = (u32)tmpaddr;

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		errno = SYNC_ERROR;
		return ret;
	}

	cmdbuf[0x100>>2] = saved_threadstorage[0];
	cmdbuf[0x104>>2] = saved_threadstorage[1];
	cmdbuf[0x108>>2] = saved_threadstorage[2];
	cmdbuf[0x10c>>2] = saved_threadstorage[3];

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		errno = -ret;
		return -1;
	}

	if(src_addr != NULL) {
		src_addr->sa_family = tmpaddr[1];
		if(*addrlen > tmpaddr[0])
			*addrlen = tmpaddr[0];
		memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
	}

	return ret;
}
示例#6
0
void dump_result_value(Result val)
{
   if(-val < 0x80)
   {
      printf("%li(%li) : %s\n", val, _net_convert_error(val), strerror(-_net_convert_error(val)));
      return;
   }

   ctr_result_value res;
   res.val = val;
   printf("0x%08X :\n", (unsigned int)val);
//   if(val == -1)
//      return;

   printf("%-4u: %s\n", res.description, ctr_error_to_str(error_description_str, res.description));
   printf("%-4u: %s\n", res.module, ctr_error_to_str(error_module_str, res.module));
   printf("%-4u: %s\n", res.summary, ctr_error_to_str(error_summary_str, res.summary));
   printf("%-4u: %s\n\n", res.level, ctr_error_to_str(error_level_str, res.level));
}
示例#7
0
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();
	u32 saved_threadstorage[2];
	u8 tmpaddr[0x1c];

	sockfd = soc_get_fd(sockfd);
	if(sockfd < 0)	{
		errno = -sockfd;
		return -1;
	}

	cmdbuf[0] = IPC_MakeHeader(0x17,2,2); // 0x170082
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = 0x1c;
	cmdbuf[3] = IPC_Desc_CurProcessHandle();

	u32 * staticbufs = getThreadStaticBuffers();
	saved_threadstorage[0] = staticbufs[0];
	saved_threadstorage[1] = staticbufs[1];

	staticbufs[0] = IPC_Desc_StaticBuffer(0x1c,0);
	staticbufs[1] = (u32)tmpaddr;

	ret = svcSendSyncRequest(SOCU_handle);

	staticbufs[0] = saved_threadstorage[0];
	staticbufs[1] = saved_threadstorage[1];

	if(ret != 0) {
		errno = SYNC_ERROR;
		return ret;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		errno = -ret;
		return -1;
	}

	if(*addrlen > tmpaddr[0])
		*addrlen = tmpaddr[0];
	memset(addr, 0, sizeof(struct sockaddr));
	addr->sa_family = tmpaddr[1];
	memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);

	return ret;
}
示例#8
0
int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
    Result ret = 0;
    int tmp_addrlen = 0x1c;

    u32 *cmdbuf = getThreadCommandBuffer();
    u8 tmpaddr[0x1c];
    u32 saved_threadstorage[2];

    memset(tmpaddr, 0, 0x1c);

    cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082
    cmdbuf[1] = (u32)sockfd;
    cmdbuf[2] = (u32)tmp_addrlen;
    cmdbuf[3] = IPC_Desc_CurProcessHandle();

    u32 *staticbufs = getThreadStaticBuffers();
    saved_threadstorage[0] = staticbufs[0];
    saved_threadstorage[1] = staticbufs[1];

    staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
    staticbufs[1] = (u32)tmpaddr;

    ret = svcSendSyncRequest(SOCU_handle);

    staticbufs[0] = saved_threadstorage[0];
    staticbufs[1] = saved_threadstorage[1];

    if(ret != 0)
        return ret;

    ret = (int)cmdbuf[1];
    if(ret == 0)
        ret = _net_convert_error(cmdbuf[2]);

    if(ret < 0)
        //errno = -ret;

    if(ret >= 0 && addr != NULL)
    {
        addr->sa_family = tmpaddr[1];
        if(*addrlen > tmpaddr[0])
            *addrlen = tmpaddr[0];
        memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
    }

    if(ret < 0)
        return -1;

    return ret;
}
示例#9
0
int socPoll(struct pollfd *fds, nfds_t nfds, int timeout)
{
    int ret = 0;
    nfds_t i;
    u32 size = sizeof(struct pollfd)*nfds;
    u32 *cmdbuf = getThreadCommandBuffer();
    u32 saved_threadstorage[2];

    if(nfds == 0) {
        return -1;
    }

    for(i = 0; i < nfds; ++i) {
        fds[i].revents = 0;
    }

    cmdbuf[0] = IPC_MakeHeader(0x14,2,4); // 0x140084
    cmdbuf[1] = (u32)nfds;
    cmdbuf[2] = (u32)timeout;
    cmdbuf[3] = IPC_Desc_CurProcessHandle();
    cmdbuf[5] = IPC_Desc_StaticBuffer(size,10);
    cmdbuf[6] = (u32)fds;

    u32 * staticbufs = getThreadStaticBuffers();
    saved_threadstorage[0] = staticbufs[0];
    saved_threadstorage[1] = staticbufs[1];

    staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
    staticbufs[1] = (u32)fds;

    ret = svcSendSyncRequest(SOCU_handle);

    staticbufs[0] = saved_threadstorage[0];
    staticbufs[1] = saved_threadstorage[1];

    if(ret != 0) {
        return ret;
    }

    ret = (int)cmdbuf[1];
    if(ret == 0)
        ret = _net_convert_error(cmdbuf[2]);

    if(ret < 0) {
        //errno = -ret;
        return -1;
    }

    return ret;
}
示例#10
0
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();
	u32 saved_threadstorage[2];

	sockfd = soc_get_fd(sockfd);
	if(sockfd < 0) {
		errno = -sockfd;
		return -1;
	}

	cmdbuf[0] = IPC_MakeHeader(0x11,4,2); // 0x110102
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = (u32)level;
	cmdbuf[3] = (u32)optname;
	cmdbuf[4] = (u32)*optlen;
	cmdbuf[5] = IPC_Desc_CurProcessHandle();

	u32 * staticbufs = getThreadStaticBuffers();
	saved_threadstorage[0] = staticbufs[0];
	saved_threadstorage[1] = staticbufs[1];

	staticbufs[0] = IPC_Desc_StaticBuffer(*optlen,0);
	staticbufs[1] = (u32)optval;

	ret = svcSendSyncRequest(SOCU_handle);

	staticbufs[0] = saved_threadstorage[0];
	staticbufs[1] = saved_threadstorage[1];

	if(ret != 0) {
		errno = SYNC_ERROR;
		return ret;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		errno = -ret;
		return -1;
	}

	*optlen = cmdbuf[3];

	return ret;
}
示例#11
0
int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    Result ret = 0;
    socklen_t tmp_addrlen = 0;
    u32 *cmdbuf = getThreadCommandBuffer();
    u8 tmpaddr[0x1c];

    memset(tmpaddr, 0, 0x1c);

    if(addr->sa_family == AF_INET)
        tmp_addrlen = 8;
    else
        tmp_addrlen = 0x1c;

    if(addrlen < tmp_addrlen)
    {
        //errno = EINVAL;
        return -1;
    }

    tmpaddr[0] = tmp_addrlen;
    tmpaddr[1] = addr->sa_family;
    memcpy(&tmpaddr[2], &addr->sa_data, tmp_addrlen-2);

    cmdbuf[0] = IPC_MakeHeader(0x5,2,4); // 0x50084
    cmdbuf[1] = (u32)sockfd;
    cmdbuf[2] = (u32)tmp_addrlen;
    cmdbuf[3] = IPC_Desc_CurProcessHandle();
    cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
    cmdbuf[6] = (u32)tmpaddr;

    ret = svcSendSyncRequest(SOCU_handle);
    if(ret != 0) {
        //errno = SYNC_ERROR;
        return ret;
    }

    ret = (int)cmdbuf[1];
    if(ret == 0)
        ret = _net_convert_error(cmdbuf[2]);

    if(ret < 0) {
        //errno = -ret;
        return -1;
    }

    return ret;
}
示例#12
0
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
    int ret=0;
    u32 *cmdbuf = getThreadCommandBuffer();
    u32 saved_threadstorage[2];
    u8 tmpaddr[0x1c];

    cmdbuf[0] = 0x00170082;
    cmdbuf[1] = (u32)sockfd;
    cmdbuf[2] = 0x1c;
    cmdbuf[3] = 0x20;

    saved_threadstorage[0] = cmdbuf[0x100>>2];
    saved_threadstorage[1] = cmdbuf[0x104>>2];

    cmdbuf[0x100>>2] = (0x1c<<14) | 2;
    cmdbuf[0x104>>2] = (u32)tmpaddr;

    if((ret = svcSendSyncRequest(SOCU_handle))!=0)return ret;

    cmdbuf[0x100>>2] = saved_threadstorage[0];
    cmdbuf[0x104>>2] = saved_threadstorage[1];

    ret = (int)cmdbuf[1];
    if(ret==0)ret = _net_convert_error(cmdbuf[2]);
    if(ret<0)SOCU_errno = ret;

    if(ret==0)
    {
        if(*addrlen > tmpaddr[0])*addrlen = tmpaddr[0];
        memset(addr, 0, sizeof(struct sockaddr));
        addr->sa_family = tmpaddr[1];
        memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
    }

    if(ret<0)return -1;
    return ret;
}
示例#13
0
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
	int ret = 0;
	nfds_t i;
	u32 size = sizeof(struct pollfd)*nfds;
	u32 *cmdbuf = getThreadCommandBuffer();
	u32 saved_threadstorage[2];

	if(nfds == 0) {
		errno = EINVAL;
		return -1;
	}

	struct pollfd *tmp_fds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
	if(tmp_fds == NULL) {
		errno = ENOMEM;
		return -1;
	}

	memcpy(tmp_fds, fds, sizeof(struct pollfd) * nfds);

	for(i = 0; i < nfds; ++i) {
		tmp_fds[i].fd = soc_get_fd(fds[i].fd);
		if(tmp_fds[i].fd < 0) {
			errno = -tmp_fds[i].fd;
			free(tmp_fds);
			return -1;
		}
		tmp_fds[i].revents = 0;
	}

	cmdbuf[0] = IPC_MakeHeader(0x14,2,4); // 0x140084
	cmdbuf[1] = (u32)nfds;
	cmdbuf[2] = (u32)timeout;
	cmdbuf[3] = IPC_Desc_CurProcessHandle();
	cmdbuf[5] = IPC_Desc_StaticBuffer(size,10);
	cmdbuf[6] = (u32)tmp_fds;

	u32 * staticbufs = getThreadStaticBuffers();
	saved_threadstorage[0] = staticbufs[0];
	saved_threadstorage[1] = staticbufs[1];

	staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
	staticbufs[1] = (u32)tmp_fds;

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		free(tmp_fds);
		errno = SYNC_ERROR;
		return ret;
	}

	staticbufs[0] = saved_threadstorage[0];
	staticbufs[1] = saved_threadstorage[1];

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		free(tmp_fds);
		errno = -ret;
		return -1;
	}

	for(i = 0; i < nfds; ++i)
		fds[i].revents = tmp_fds[i].revents;

	free(tmp_fds);

	return ret;
}
示例#14
0
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
	int ret = 0;
	int tmp_addrlen = 0x1c;
	int fd, dev;
	__handle *handle;
	u32 *cmdbuf = getThreadCommandBuffer();
	u8 tmpaddr[0x1c];
	u32 saved_threadstorage[2];

	sockfd = soc_get_fd(sockfd);
	if(sockfd < 0) {
		errno = -sockfd;
		return -1;
	}

	dev = FindDevice("soc:");
	if(dev < 0) {
		errno = ENODEV;
		return -1;
	}

	fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
	if(fd < 0) {
		errno = ENOMEM;
		return -1;
	}

	handle = __get_handle(fd);
	handle->device = dev;
	handle->fileStruct = ((void *)handle) + sizeof(__handle);

	memset(tmpaddr, 0, 0x1c);

	cmdbuf[0] = IPC_MakeHeader(0x4,2,2); // 0x40082
	cmdbuf[1] = (u32)sockfd;
	cmdbuf[2] = (u32)tmp_addrlen;
	cmdbuf[3] = IPC_Desc_CurProcessHandle();

	u32 * staticbufs = getThreadStaticBuffers();
	saved_threadstorage[0] = staticbufs[0];
	saved_threadstorage[1] = staticbufs[1];

	staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
	staticbufs[1] = (u32)tmpaddr;

	ret = svcSendSyncRequest(SOCU_handle);
	
	staticbufs[0] = saved_threadstorage[0];
	staticbufs[1] = saved_threadstorage[1];
	
	if(ret != 0) {
		__release_handle(fd);
		errno = SYNC_ERROR;
		return ret;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0)
		errno = -ret;

	if(ret >= 0 && addr != NULL) {
		addr->sa_family = tmpaddr[1];
		if(*addrlen > tmpaddr[0])
			*addrlen = tmpaddr[0];
		memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
	}

	if(ret < 0) {
		__release_handle(fd);
		return -1;
	}
	else
		*(Handle*)handle->fileStruct = ret;

	return fd;
}
示例#15
0
int socket(int domain, int type, int protocol)
{
	int ret = 0;
	int fd, dev;
	__handle *handle;
	u32 *cmdbuf = getThreadCommandBuffer();

	// The protocol on the 3DS *must* be 0 to work
	// To that end, when appropriate, we will make the change for the user
	if (domain == AF_INET
	&& type == SOCK_STREAM
	&& protocol == IPPROTO_TCP) {
		protocol = 0; // TCP is the only option, so 0 will work as expected
	}
	if (domain == AF_INET
	&& type == SOCK_DGRAM
	&& protocol == IPPROTO_UDP) {
		protocol = 0; // UDP is the only option, so 0 will work as expected
	}

	cmdbuf[0] = IPC_MakeHeader(0x2,3,2); // 0x200C2
	cmdbuf[1] = domain;
	cmdbuf[2] = type;
	cmdbuf[3] = protocol;
	cmdbuf[4] = IPC_Desc_CurProcessHandle();

	dev = FindDevice("soc:");
	if(dev < 0) {
		errno = ENODEV;
		return -1;
	}

	fd = __alloc_handle(sizeof(__handle) + sizeof(Handle));
	if(fd < 0) {
		errno = ENOMEM;
		return -1;
	}

	handle = __get_handle(fd);
	handle->device = dev;
	handle->fileStruct = ((void *)handle) + sizeof(__handle);

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0)
	{
		__release_handle(fd);
		errno = SYNC_ERROR;
		return ret;
	}

	ret = (int)cmdbuf[1];
	if(ret == 0)ret = cmdbuf[2];
	if(ret < 0) {
		__release_handle(fd);
		if(cmdbuf[1] == 0)errno = _net_convert_error(ret);
		if(cmdbuf[1] != 0)errno = SYNC_ERROR;
		return -1;
	}

	*(Handle*)handle->fileStruct = cmdbuf[2];
	return fd;
}
示例#16
0
struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();
	u32 saved_threadstorage[2];
	static u8 outbuf[0x1A88];

	h_errno = 0;

	cmdbuf[0] = 0x000E00C2;
	cmdbuf[1] = len;
	cmdbuf[2] = type;
	cmdbuf[3] = sizeof(outbuf);
	cmdbuf[4] = (len << 14) | 0x1002;
	cmdbuf[5] = (u32)addr;

	saved_threadstorage[0] = cmdbuf[0x100>>2];
	saved_threadstorage[1] = cmdbuf[0x104>>2];

	cmdbuf[0x100>>2] = (sizeof(outbuf) << 14) | 2;
	cmdbuf[0x104>>2] = (u32)outbuf;

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		h_errno = NO_RECOVERY;
		return NULL;
	}


	cmdbuf[0x100>>2] = saved_threadstorage[0];
	cmdbuf[0x104>>2] = saved_threadstorage[1];

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

	if(ret < 0) {
		/* TODO: set h_errno based on ret */
		h_errno = HOST_NOT_FOUND;
		return NULL;
	}

	u32 num_results, i;
	memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
	if(num_results > MAX_HOSTENT_RESULTS)
		num_results = MAX_HOSTENT_RESULTS;

	SOC_hostent.h_name      = (char*)outbuf + 8;
	SOC_hostent.h_aliases   = &SOC_hostent_alias;
	SOC_hostent.h_addrtype  = AF_INET;
	SOC_hostent.h_length    = 4;
	SOC_hostent.h_addr_list = SOC_hostent_results;

	SOC_hostent_alias = NULL;

	for(i = 0; i < num_results; ++i)
		SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
	SOC_hostent_results[num_results] = NULL;

	SOC_hostent.h_addr = SOC_hostent.h_addr_list[0];

	return &SOC_hostent;
}
示例#17
0
struct hostent* gethostbyname(const char *name)
{
	int ret = 0;
	u32 *cmdbuf = getThreadCommandBuffer();
	u32 saved_threadstorage[2];
	static u8 outbuf[0x1A88];

	h_errno = 0;

	cmdbuf[0] = IPC_MakeHeader(0xD,2,2); // 0xD0082
	cmdbuf[1] = strlen(name)+1;
	cmdbuf[2] = sizeof(outbuf);
	cmdbuf[3] = ((strlen(name)+1) << 14) | 0xC02;
	cmdbuf[4] = (u32)name;

	u32 * staticbufs = getThreadStaticBuffers();
	saved_threadstorage[0] = staticbufs[0];
	saved_threadstorage[1] = staticbufs[1];

	staticbufs[0] = IPC_Desc_StaticBuffer(sizeof(outbuf),0);
	staticbufs[1] = (u32)outbuf;

	ret = svcSendSyncRequest(SOCU_handle);
	if(ret != 0) {
		h_errno = NO_RECOVERY;
		return NULL;
	}

	staticbufs[0] = saved_threadstorage[0];
	staticbufs[1] = saved_threadstorage[1];

	ret = (int)cmdbuf[1];
	if(ret == 0)
		ret = _net_convert_error(cmdbuf[2]);

        if(ret < 0) {
		/* TODO: set h_errno based on ret */
		h_errno = HOST_NOT_FOUND;
		return NULL;
	}

	u32 num_results, i;
	memcpy(&num_results, (char*)outbuf+4, sizeof(num_results));
	if(num_results > MAX_HOSTENT_RESULTS)
		num_results = MAX_HOSTENT_RESULTS;

	SOC_hostent.h_name      = (char*)outbuf + 8;
	SOC_hostent.h_aliases   = &SOC_hostent_alias;
	SOC_hostent.h_addrtype  = AF_INET;
	SOC_hostent.h_length    = 4;
	SOC_hostent.h_addr_list = SOC_hostent_results;

	SOC_hostent_alias = NULL;

	for(i = 0; i < num_results; ++i)
		SOC_hostent_results[i] = (char*)outbuf + 0x1908 + i*0x10;
	SOC_hostent_results[num_results] = NULL;

	SOC_hostent.h_addr = SOC_hostent.h_addr_list[0];

	return &SOC_hostent;
}