コード例 #1
0
ファイル: menu.c プロジェクト: k-takata/TClockLight
/*------------------------------------------------
  add commands to MENUSTRUCT and HMENU
--------------------------------------------------*/
int ReadMenuCommands(HMENU hmenu, const char *p,
	MENUSTRUCT* pmenus)
{
	int count = 0;
	int idCommand = 1;
	char name[81], command[MAX_PATH];
	
	while(*p)
	{
		if(*p == '#' ||
			*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
		{
			p = nextline(p);
		}
		else if(*p == '-' && *(p + 1) == '-')
		{
			if(hmenu)
				AppendMenu(hmenu, MF_SEPARATOR, 0, 0);
			p = nextline(p);
		}
		else
		{
			BOOL bdigit;
			int id, i;
			char quot;
			
			quot = 0;
			if(*p == '\"' || *p == '\'') { quot = *p; p++; }
			for(i = 0; i < 80 &&
				*p && *p != '\r' && *p != '\n'; i++)
			{
				if(quot) { if(*p == quot) { p++; break; } }
				else if(*p == ' ' || *p == '\t') break;
				name[i] = *p++;
			}
			name[i] = 0;
			while(*p == ' ' || *p == '\t') p++;
			
			quot = 0;
			if(*p == '\"' || *p == '\'') { quot = *p; p++; }
			for(i = 0; i < MAX_PATH-1 &&
				*p && *p != '\r' && *p != '\n'; i++)
			{
				if(quot && *p == quot) break;
				command[i] = *p++;
			}
			command[i] = 0;
			
			bdigit = isdigitstr(command);
			if(bdigit) id = atoi(command);
			else id = idCommand;
			
			if(hmenu)
				AppendMenu(hmenu, MF_STRING, id, name);
			
			if(!bdigit)
			{
				if(pmenus)
				{
					pmenus[count].id = id;
					strcpy(pmenus[count].command, command);
				}
				count++;
				if(count >= 50) return count;
				idCommand++;
			}
			
			p = nextline(p);
		}
	}
	
	return count;
}
コード例 #2
0
ファイル: addr.c プロジェクト: srsbsns/libsrsbsns
int addr_mksocket(const char *host, const char *service,
    int socktype, int aflags, conbind_t func,
    struct sockaddr *sockaddr, size_t *addrlen,
    int64_t softto_us, int64_t hardto_us)
{
	D("invoked: host='%s', serv='%s', scktype: %d, aflags: %d, func: %s, sto=%lu, hto=%lu", host, service, socktype, aflags, !func ? "(none)" : func == connect ? "connect" : func == bind ? "bind" : "(unkonwn)", softto_us, hardto_us);

	struct addrinfo *ai_list = NULL;
	struct addrinfo hints;
	int64_t hardtsend = hardto_us ? tstamp_us() + hardto_us : 0;
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = socktype;
	hints.ai_protocol = 0;
	hints.ai_flags = aflags;
	if (isdigitstr(service))
		hints.ai_flags |= AI_NUMERICSERV;


	D("calling getaddrinfo on '%s:%s'", host, service);

	int r = getaddrinfo(host, service, &hints, &ai_list);

	if (r != 0) {
		W("getaddrinfo() failed: %s", gai_strerror(r));
		return -1;
	}

	if (!ai_list) {
		W("getaddrinfo() result address list empty");
		return -1;
	}

	bool success = false;
	int sck = -1;

	D("iterating over result list...");
	for (struct addrinfo *ai = ai_list; ai; ai = ai->ai_next) {
		sck = -1;
		if (hardtsend && hardtsend - tstamp_us() <= 0) {
			W("hard timeout");
			return 0;
		}

		D("next result, creating socket (fam=%d, styp=%d, prot=%d)",
		    ai->ai_family, ai->ai_socktype, ai->ai_protocol);

		sck = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (sck < 0) {
			WE("cannot create socket");
			continue;
		}

		char peeraddr[64] = "(non-INET/INET6)";
		unsigned short peerport = 0;

		if (ai->ai_family == AF_INET) {
			struct sockaddr_in *sin =
			    (struct sockaddr_in*)ai->ai_addr;

			inet_ntop(AF_INET, &sin->sin_addr,
			    peeraddr, sizeof peeraddr);

			peerport = ntohs(sin->sin_port);
		} else if (ai->ai_family == AF_INET6) {
			struct sockaddr_in6 *sin =
			    (struct sockaddr_in6*)ai->ai_addr;

			inet_ntop(AF_INET6, &sin->sin6_addr,
			    peeraddr, sizeof peeraddr);

			peerport = ntohs(sin->sin6_port);
		}

		char portstr[7];
		snprintf(portstr, sizeof portstr, ":%hu", peerport);
		strNcat(peeraddr, portstr, sizeof peeraddr);

		int opt = 1;
		socklen_t optlen = sizeof opt;

		D("peer addr is '%s'", peeraddr);

		if (sockaddr)
			*sockaddr = *(ai->ai_addr);
		if (addrlen)
			*addrlen = ai->ai_addrlen;
		
		if (func) {
			D("going non-blocking");
			if (setblocking(sck, false) == -1) {
				WE("failed to enable nonblocking mode");
				close(sck);
				continue;
			}

			D("set to nonblocking mode, calling the backend function...");
			errno = 0;
			bool doselect = false;
			int r = func(sck, ai->ai_addr, ai->ai_addrlen);

			if (r == -1 && (errno != EINPROGRESS)) {
				WE("backend failed");
				close(sck);
				continue;
			} else if (r == -1)
				doselect = true;

			int64_t trem = 0;
			D("backend returned with %d", r);
			if (doselect) {
				if (hardtsend) {
					trem = hardtsend - tstamp_us();
					if (trem <= 0) {
						D("hard timeout detected");
						close(sck);
						continue;
					}
				}

				int64_t softtsend = softto_us ? tstamp_us() + softto_us : 0;

				if (softtsend) {
					int64_t trem_tmp = softtsend - tstamp_us();

					if (trem_tmp <= 0) {
						W("soft timeout");
						close(sck);
						continue;
					}

					if (trem_tmp < trem)
						trem = trem_tmp;
				}

				D("calling io_select1w (timeout: %lld us)", trem);
				r = io_select1w(sck, trem, true);

				if (r < 0) {
					WE("select() failed");
					close(sck);
					continue;
				} else if (!r) {
					W("select() timeout");
					close(sck);
					continue;
				} else
					D("selected!");

				D("calling getsockopt to query error state");
				if (getsockopt(sck, SOL_SOCKET, SO_ERROR, &opt, &optlen) != 0) {
					W("getsockopt failed");
					close(sck);
					continue;
				}

				if (opt == 0) {
					I("socket in good shape! ('%s')", peeraddr);
					if (setblocking(sck, true) == -1) {
						WE("failed to disable nonblocking mode");
						close(sck);
						continue;
					}
					success = true;
					break;
				} else {
					char errstr[256];
					strerror_r(opt, errstr, sizeof errstr);
					W("backend function failed (%d: %s)", opt, errstr);
					close(sck);
					continue;
				}
			} else {
				I("There we go... ('%s')", peeraddr);
				if (setblocking(sck, true) == -1) {
					WE("failed to disable nonblocking mode");
					close(sck);
					continue;
				}
				success = true;
				break;
			}

		} else {
			success = true;
			break;
		}
	}
	
	D("after loop; alling freeaddrinfo then returning %d", sck);

	freeaddrinfo(ai_list);

	return success ? sck : -1;
}