Example #1
0
File: connect.c Project: tongfw/pcp
void
__pmConnectGetPorts(pmHostSpec *host)
{
    PM_INIT_LOCKS();
    PM_LOCK(__pmLock_libpcp);
    load_pmcd_ports();
    if (__pmAddHostPorts(host, global_portlist, global_nports) < 0) {
	__pmNotifyErr(LOG_WARNING,
		"__pmConnectGetPorts: portlist dup failed, "
		"using default PMCD_PORT (%d)\n", SERVER_PORT);
	host->ports[0] = SERVER_PORT;
	host->nports = 1;
    }
    PM_UNLOCK(__pmLock_libpcp);
}
Example #2
0
File: spec.c Project: goodwinos/pcp
/*
 * Parse a host specification, with optional ports and proxy host(s).
 * Examples:
 *	pcp -h app1.aconex.com:44321,[email protected]:44322
 *	pcp -h app1.aconex.com:[email protected]:44322
 *	pcp -h app1.aconex.com:[email protected]
 *	pcp -h [email protected]
 *	pcp -h app1.aconex.com:44321
 *      pcp -h 192.168.122.1:44321
 *      pcp -h [fe80::5eff:35ff:fe07:55ca]:44321,4321@[fe80::5eff:35ff:fe07:55cc]:44322
 *      pcp -h [fe80::5eff:35ff:fe07:55ca]:44321
 *
 * Basic algorithm:
 *	look for first colon, @ or null; preceding text is hostname
 *	 if colon, look for comma, @ or null, preceding text is port
 *	  while comma, look for comma, @ or null, preceding text is next port
 *	if @, start following host specification at the following character,
 *	 by returning to the start and repeating the above for the next chunk.
 * Note:
 *      IPv6 addresses contain colons and, so, must be separated from the
 *      rest of the spec somehow. A common notation among ipv6-enabled
 *      applications is to enclose the address within brackets, as in
 *      [fe80::5eff:35ff:fe07:55ca]:44321. We keep it simple, however,
 *      and allow any host spec to be enclosed in brackets.
 * Note:
 *	Currently only two hosts are useful, but ability to handle more than
 *	one optional proxy host is there (i.e. proxy ->proxy ->... ->pmcd),
 *	in case someone implements the pmproxy->pmproxy protocol extension.
 */
static int      /* 0 -> ok, PM_ERR_GENERIC -> error message is set */
parseHostSpec(
    const char *spec,
    char **position,            /* parse this string, return end char */
    pmHostSpec **rslt,          /* result allocated and returned here */
    int *count,
    char **errmsg)              /* error message */
{
    pmHostSpec *hsp = NULL;
    const char *s, *start, *next;
    int nhosts = 0, sts = 0;

    for (s = start = *position; s != NULL; s++) {
	/* Allow the host spec to be enclosed in brackets. */
	if (s == start && *s == '[') {
	    for (s++; *s != ']' && *s != '\0'; s++)
		;
	    if (*s != ']') {
		hostError(spec, s, "missing closing ']' for host spec", errmsg);
		sts = PM_ERR_GENERIC;
		goto fail;
	    }
	    next = s + 1; /* past the trailing ']' */
	    if (*next != ':' && *next != '@' && *next != '\0' && *next != '/' && *next != '?') {
		hostError(spec, next, "extra characters after host spec", errmsg);
		sts = PM_ERR_GENERIC;
		goto fail;
	    }
	    start++; /* past the initial '[' */
	}
	else
	    next = s;
	if (*next == ':' || *next == '@' || *next == '\0' || *next == '/' || *next == '?') {
	    if (s == *position)
		break;
	    else if (s == start)
		continue;
	    hsp = hostAdd(hsp, &nhosts, start, s - start);
	    if (hsp == NULL) {
		sts = -ENOMEM;
		goto fail;
	    }
	    s = next;
	    if (*s == ':') {
		for (++s, start = s; s != NULL; s++) {
		    if (*s == ',' || *s == '@' || *s == '\0' || *s == '/' || *s == '?') {
			if (s - start < 1) {
			    hostError(spec, s, "missing port", errmsg);
			    sts = PM_ERR_GENERIC;
			    goto fail;
			}
			int port = atoi(start);
			sts = __pmAddHostPorts(&hsp[nhosts-1], &port, 1);
			if (sts < 0)
			    goto fail;
			start = s + 1;
			if (*s == '@' || *s == '\0' || *s == '/' || *s == '?')
			    break;
			continue;
		    }
		    if (isdigit((int)*s))
			continue;
		    hostError(spec, s, "non-numeric port", errmsg);
		    sts = PM_ERR_GENERIC;
		    goto fail;
		}
	    }
	    if (*s == '@') {
		start = s+1;
		continue;
	    }
	    break;
	}
    }
    *position = (char *)s;
    *count = nhosts;
    *rslt = hsp;
    return 0;

fail:
    __pmFreeHostSpec(hsp, nhosts);
    *rslt = NULL;
    *count = 0;
    return sts;
}