コード例 #1
0
ファイル: multisock.c プロジェクト: K6BSD/SBBSUnstable
BOOL DLLCALL xpms_add(struct xpms_set *xpms_set, int domain, int type,
	int protocol, const char *addr, uint16_t port, const char *prot, 
	void (*sock_init)(SOCKET, void *), int(*bind_init)(BOOL), void *cbdata)
{
	struct xpms_sockdef	*new_socks;
    struct addrinfo		hints;
    struct addrinfo		*res=NULL;
    struct addrinfo		*cur;
    unsigned int		added = 0;
    int					ret;
    char				port_str[6];

#ifndef _WIN32
	struct addrinfo		dummy;
	struct sockaddr_un	un_addr;

	if(domain == AF_UNIX) {
		memset(&dummy, 0, sizeof(dummy));
		dummy.ai_family = AF_UNIX;
		dummy.ai_socktype = type;
		dummy.ai_addr = (struct sockaddr *)&un_addr;
		un_addr.sun_family=AF_UNIX;

		if(strlen(addr) >= sizeof(un_addr.sun_path)) {
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_ERR, "!ERROR %s is too long for a portable AF_UNIX socket", addr);
			return FALSE;
		}
		strcpy(un_addr.sun_path,addr);
		if(fexist(addr))
			unlink(addr);
		dummy.ai_addrlen = sizeof(un_addr);
		un_addr.sun_len=SUN_LEN(&un_addr);
		res = &dummy;
	}
#endif
	if(res == NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_flags=AI_PASSIVE;
		hints.ai_family=domain;
		hints.ai_socktype=type;
		hints.ai_protocol=protocol;
		hints.ai_flags|=AI_NUMERICSERV;
#ifdef AI_ADDRCONFIG
		hints.ai_flags|=AI_ADDRCONFIG;
#endif
		sprintf(port_str, "%hu", port);
		if((ret=getaddrinfo(addr, port_str, &hints, &res))!=0) {
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_CRIT, "!ERROR %d calling getaddrinfo() on %s", ret, addr);
			return FALSE;
		}
	}

	for(cur=res; cur; cur=cur->ai_next) {
		new_socks=(struct xpms_sockdef *)realloc(xpms_set->socks, sizeof(struct xpms_sockdef)*(xpms_set->sock_count+1));
		if(new_socks==NULL) {
			/* This may be a partial failure */
			if(xpms_set->lprintf)
				xpms_set->lprintf(LOG_CRIT, "!ERROR out of memory adding to multisocket");
			break;
		}
		xpms_set->socks=new_socks;
		xpms_set->socks[xpms_set->sock_count].address = strdup(addr);
		xpms_set->socks[xpms_set->sock_count].cb_data = cbdata;
		xpms_set->socks[xpms_set->sock_count].domain = cur->ai_family;	/* Address/Protocol Family */
		xpms_set->socks[xpms_set->sock_count].type = cur->ai_socktype;
		xpms_set->socks[xpms_set->sock_count].protocol = protocol;
		xpms_set->socks[xpms_set->sock_count].port = port;
		xpms_set->socks[xpms_set->sock_count].prot = strdup(prot);
		xpms_set->socks[xpms_set->sock_count].sock = socket(cur->ai_family, cur->ai_socktype, protocol);
		if(xpms_set->socks[xpms_set->sock_count].sock == INVALID_SOCKET) {
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
			continue;
		}
		if(sock_init)
			sock_init(xpms_set->socks[xpms_set->sock_count].sock, cbdata);

		if(bind_init) {
			if(port < IPPORT_RESERVED && port > 0)
				bind_init(FALSE);
		}
		if(retry_bind(xpms_set->socks[xpms_set->sock_count].sock, cur->ai_addr, cur->ai_addrlen, xpms_set->retries, xpms_set->wait_secs, prot, xpms_set->lprintf)==-1) {
			closesocket(xpms_set->socks[xpms_set->sock_count].sock);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
			FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
			if(bind_init) {
				if(port < IPPORT_RESERVED)
					bind_init(TRUE);
			}
			continue;
		}
		if(bind_init) {
			if(port < IPPORT_RESERVED && port > 0)
				bind_init(TRUE);
		}

		if(type != SOCK_DGRAM) {
			if(listen(xpms_set->socks[xpms_set->sock_count].sock, SOMAXCONN)==-1) {
				if(xpms_set->lprintf)
					xpms_set->lprintf(LOG_WARNING, "%04d !ERROR %d listen()ing on port %d"
							, xpms_set->socks[xpms_set->sock_count].sock, ERROR_VALUE, port);
				closesocket(xpms_set->socks[xpms_set->sock_count].sock);
				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
				continue;
			}
		}

		added++;
		xpms_set->sock_count++;
	}

#ifndef _WIN32
	if(res != &dummy)
#endif
		freeaddrinfo(res);
	if(added)
		return TRUE;
	return FALSE;
}
コード例 #2
0
ファイル: options.c プロジェクト: laochailan/taisei
static OptionBinding* bind_new(void) {
	OptionBinding *bind = malloc(sizeof(OptionBinding));
	bind_init(bind);
	return bind;
}