Пример #1
0
/*
 * This function will remove any trailing periods from domain, after which it
 * returns a pointer to newly allocated memory containing the whois server to
 * be queried, or a NULL if the correct server couldn't be determined.  The
 * caller must remember to free(3) the allocated memory.
 */
static char *
choose_server(char *domain)
{
	char *pos, *retval;

	for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
		*pos = '\0';
	if (*domain == '\0')
		errx(EX_USAGE, "can't search for a null string");
	if (strlen(domain) > sizeof("-NORID")-1 &&
	    strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1,
		"-NORID") == 0) {
		s_asprintf(&retval, "%s", NORIDHOST);
		return (retval);
	}
	while (pos > domain && *pos != '.')
		--pos;
	if (pos <= domain)
		return (NULL);
	if (isdigit((unsigned char)*++pos))
		s_asprintf(&retval, "%s", ANICHOST);
	else
		s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL);
	return (retval);
}
Пример #2
0
char *
sosc_get_default_config_dir(void)
{
	char *dir;

	if (getenv("XDG_CONFIG_HOME"))
		dir = s_asprintf("%s/serialosc", getenv("XDG_CONFIG_HOME"));
	else
		dir = s_asprintf("%s/.config/serialosc", getenv("HOME"));

	return dir;
}
Пример #3
0
S_API char *s_str_list_to_string(s_str_list *self, const char *separator,
								 s_erc *error)
{
	char *buf = NULL;
	const s_str_list_element *itr;


	S_CLR_ERR(error);
	if ((self == NULL) || (separator == NULL))
		return NULL;

	itr = s_str_list_first(self, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_str_list_to_string",
				  "Call to \"s_str_list_first\" failed"))
		goto error_return;

	while (itr != NULL)
	{
		const char *element;


		element = s_str_list_element_get(itr, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "s_str_list_to_string",
					  "Call to \"s_str_list_element_get\" failed"))
			goto error_return;

		if (buf == NULL)
			s_asprintf(&buf, error, "%s", element);
		else
			s_asprintf(&buf, error, "%s%s%s", buf, separator, element);

		if (S_CHK_ERR(error, S_CONTERR,
					  "s_str_list_to_string",
					  "Call to \"s_asprintf\" failed"))
			goto error_return;

		itr = s_str_list_element_next(itr, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "s_str_list_merge",
					  "Call to \"s_str_list_element_next\" failed"))
			goto error_return;
	}

	return buf;

error_return:
	if (buf != NULL)
		S_FREE(buf);

	return NULL;
}
Пример #4
0
int
sosc_config_create_directory(void)
{
	char *cdir, *xdgdir;
	struct stat buf[1];

	cdir = sosc_get_default_config_dir();

	if (stat(cdir, buf)) {
		if (!getenv("XDG_CONFIG_HOME")) {
			xdgdir = s_asprintf("%s/.config", getenv("HOME"));

			/* well, I guess somebody's got to do it */
			if (stat(xdgdir, buf) && mkdir(xdgdir, S_IRWXU))
				goto err_xdg;

			s_free(xdgdir);
		}

		if (mkdir(cdir, S_IRWXU))
			goto err_mkdir;
	}

	s_free(cdir);
	return 0;

err_xdg:
	s_free(xdgdir);
err_mkdir:
	s_free(cdir);
	return 1;
}
Пример #5
0
static void textgrid_header(SDatasource *ds, float end_time, int size, s_erc *error)
{
	const char *str = "File type = \"ooTextFile\"\nObject class = \"TextGrid\"\n\nxmin = 0\nxmax = %f\ntiers? <exists>\nsize = %d\nitem []:\n";
	char *buff = NULL;
	size_t str_size;


	S_CLR_ERR(error);
	s_asprintf(&buff, error, str, end_time, size);
	if (S_CHK_ERR(error, S_CONTERR,
				  "textgrid_header",
				  "Call to \"s_asprintf\" failed"))
		return;

	str_size = s_strsize(buff, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "textgrid_header",
				  "Call to \"s_strsize\" failed"))
	{
		S_FREE(buff);
		return;
	}

	SDatasourceWrite(ds, buff, sizeof(char), str_size, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "textgrid_header",
				  "Call to \"SDatasourceWrite\" failed"))
	{
		S_FREE(buff);
		return;
	}

	S_FREE(buff);
}
Пример #6
0
/*
 * This function will remove any trailing periods from domain, after which it
 * returns a pointer to newly allocated memory containing the whois server to
 * be queried, or a NULL if the correct server couldn't be determined.  The
 * caller must remember to free(3) the allocated memory.
 */
static char *
choose_server(const char *domain)
{
	char *pos, *retval;

	for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
		*pos = '\0';
	if (*domain == '\0')
		errx(EX_USAGE, "can't search for a null string");
	while (pos > domain && *pos != '.')
		--pos;
	if (pos <= domain)
		return (NULL);
	if (isdigit(*++pos))
		s_asprintf(&retval, "%s", ANICHOST);
	else
		s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL);
	return (retval);
}
Пример #7
0
/* differs from create_A_context in that previous phone's syllable is queried
 * and not previous syllable */
static char *create_A_context_pause(const SItem *item, s_erc *error)
{
	SObject *dFeat;
	char *a_context;
	sint32 a3;


	S_CLR_ERR(error);

	/* we currently cannot compute a1 and a2 */

	/* a3 */
	dFeat = SItemPathToFeatProc(item, "p.R:SylStructure.parent.R:Syllable.syllable_num_phones",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_A_context_pause",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		a3 = SObjectGetInt(dFeat, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_A_context_pause",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_A_context_pause", error);
	}
	else
	{
		a3 = 0;
	}

	/* we currently cannot compute a1 and a2 */
	s_asprintf(&a_context, error, "/A:0_0_%d", a3);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_A_context_pause",
				  "Call to \"s_asprintf\" failed"))
		return NULL;

	return a_context;
}
Пример #8
0
/* differs from create_C_context in that next phone's syllable is queried
 * and not next syllable */
static char *create_C_context_pause(const SItem *item, s_erc *error)
{
	SObject *dFeat;
	char *c_context;
	sint32 c3;


	S_CLR_ERR(error);

	/* we currently cannot compute c1 and c2 */

	/* c3 */
	dFeat = SItemPathToFeatProc(item, "n.R:SylStructure.parent.R:Syllable.syllable_num_phones",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_C_context_pause",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		c3 = SObjectGetInt(dFeat, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_C_context_pause",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_C_context_pause", error);
	}
	else
	{
		c3 = 0;
	}

	/* we currently cannot compute c1 and c2 */
	s_asprintf(&c_context, error, "/C:0+0+%d", c3);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_C_context_pause",
				  "Call to \"s_asprintf\" failed"))
		return NULL;

	return c_context;
}
Пример #9
0
static char *PrintVoid(const SObject *self, s_erc *error)
{
    const char *type = "[SVoid] %p";
    char *buf;


    S_CLR_ERR(error);

    s_asprintf(&buf, error, type, ((SVoid*)self)->ptr);
    if (S_CHK_ERR(error, S_CONTERR,
                  "PrintVoid",
                  "Call to \"s_asprintf\" failed"))
    {
        if (buf != NULL)
            S_FREE(buf);
        return NULL;
    }

    return buf;
}
Пример #10
0
static char *PrintInt(const SObject *self, s_erc *error)
{
    const char *type = "[SInt] %d";
    sint32 i;
    char *buf;


    S_CLR_ERR(error);
    i = ((SInt*)self)->i;
    s_asprintf(&buf, error, type, i);
    if (S_CHK_ERR(error, S_FAILURE,
                  "PrintInt",
                  "Call to \"s_asprintf\" failed"))
    {
        if (buf != NULL)
            S_FREE(buf);
        return NULL;
    }

    return buf;
}
Пример #11
0
static char *PrintString(const SObject *self, s_erc *error)
{
    const char *type = "[SString] \"%s\"";
    const char *s;
    char *buf;


    S_CLR_ERR(error);
    s = ((SString*)self)->s;
    s_asprintf(&buf, error, type, s);
    if (S_CHK_ERR(error, S_FAILURE,
                  "PrintString",
                  "Call to \"s_asprintf\" failed"))
    {
        if (buf != NULL)
            S_FREE(buf);
        return NULL;
    }

    return buf;
}
Пример #12
0
static char *PrintFloat(const SObject *self, s_erc *error)
{
    const char *type = "[SFloat] %f";
    float f;
    char *buf;


    S_CLR_ERR(error);
    f = ((SFloat*)self)->f;
    s_asprintf(&buf, error, type, f);
    if (S_CHK_ERR(error, S_FAILURE,
                  "PrintFloat",
                  "Call to \"s_asprintf\" failed"))
    {
        if (buf != NULL)
            S_FREE(buf);
        return NULL;
    }

    return buf;
}
Пример #13
0
static void
whois(const char *query, const char *hostname, int flags)
{
	FILE *sfi, *sfo;
	struct addrinfo *hostres, *res;
	char *buf, *host, *nhost, *p;
	int i, s;
	size_t c, len;

	hostres = gethostinfo(hostname, 1);
	for (res = hostres; res; res = res->ai_next) {
		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if (s < 0)
			continue;
		if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
			break;
		close(s);
	}
	freeaddrinfo(hostres);
	if (res == NULL)
		err(EX_OSERR, "connect()");

	sfi = fdopen(s, "r");
	sfo = fdopen(s, "w");
	if (sfi == NULL || sfo == NULL)
		err(EX_OSERR, "fdopen()");
	if (strcmp(hostname, GERMNICHOST) == 0) {
#ifdef __APPLE__
		/* radar:18958875 radar:21503897 */
		fprintf(sfo, "-T dn -C UTF-8 %s\r\n", query);
#else
		fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
#endif
	} else {
		fprintf(sfo, "%s\r\n", query);
	}
	fflush(sfo);
	nhost = NULL;
	while ((buf = fgetln(sfi, &len)) != NULL) {
		while (len > 0 && isspace((unsigned char)buf[len - 1]))
			buf[--len] = '\0';
		printf("%.*s\n", (int)len, buf);

		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
			host = strnstr(buf, WHOIS_SERVER_ID, len);
			if (host != NULL) {
				host += sizeof(WHOIS_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				     (int)(buf + len - host), host);
			} else if ((host =
			    strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
				host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				    (int)(buf + len - host), host);
			} else if (strcmp(hostname, ANICHOST) == 0) {
				for (c = 0; c <= len; c++)
					buf[c] = tolower((int)buf[c]);
				for (i = 0; ip_whois[i] != NULL; i++) {
					if (strnstr(buf, ip_whois[i], len) !=
					    NULL) {
						s_asprintf(&nhost, "%s",
						    ip_whois[i]);
						break;
					}
				}
			}
		}
	}
	if (nhost != NULL) {
		whois(query, nhost, 0);
		free(nhost);
	}
}
Пример #14
0
static int write_relation(SDatasource *ds, const SRelation *rel,
						  int num_tiers, float end_time, s_erc *error)
{
	const char *relname;
	const SItem *head = NULL;
	const char *tier_header = "\titem [%d]:\n\t\tclass = \"IntervalTier\"\n\t\tname = \"%s\"\n";
	const char *tier_start_end = "\t\txmin = 0\n\t\txmax = %f\n";
	const char *tier_intervals = "\t\tintervals: size = %d\n";
	const char *tier_item = " \t\tintervals [%d]:\n\t\t\txmin = %f\n\t\t\txmax = %f\n\t\t\ttext = \"%s\"\n";
	char *buff;
	size_t str_size;
	float prev_end = 0.0;
	const SItem *itr;
	float item_start = 0.0;
	float item_end = 0.0;
	const char *item_name = NULL;
	SList *info;
	size_t l_size;
	int counter;
	SIterator *litr;


	S_CLR_ERR(error);
	if (rel == NULL)
		return num_tiers;

	num_tiers += 1;
	relname = SRelationName(rel, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SRelationName\" failed"))
		return 0;

	head = SRelationHead(rel, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SRelationHead\" failed"))
		return 0;

	/* tier header */
	s_asprintf(&buff, error, tier_header, num_tiers, relname);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_asprintf\" failed"))
		return 0;

	str_size = s_strsize(buff, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_strsize\" failed"))
	{
		S_FREE(buff);
		return 0;
	}

	SDatasourceWrite(ds, buff, sizeof(char), str_size, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SDatasourceWrite\" failed"))
	{
		S_FREE(buff);
		return 0;
	}

	S_FREE(buff);

	/* start time and end time (always 0 and utt end) */
	s_asprintf(&buff, error, tier_start_end, end_time);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_asprintf\" failed"))
		return 0;

	str_size = s_strsize(buff, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_strsize\" failed"))
	{
		S_FREE(buff);
		return 0;
	}

	SDatasourceWrite(ds, buff, sizeof(char), str_size, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SDatasourceWrite\" failed"))
	{
		S_FREE(buff);
		return 0;
	}

	S_FREE(buff);

	info = S_LIST(S_NEW(SListList, error));
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Failed to create new list for info cache"))
		return 0;

	prev_end = 0.0;
	itr = head;
	while (itr != NULL)
	{
		item_start = get_start(itr, relname, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"get_start\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}

		item_end = get_end(itr, relname, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"get_end\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}

		if (!s_float_equal(item_start, prev_end))
		{
			/* prepend extra "SIL" */
			add_info(info, prev_end, item_start, "SIL", error);
			if (S_CHK_ERR(error, S_CONTERR,
						  "write_relation",
						  "Call to \"add_info\" failed"))
			{
				S_DELETE(info, "write_relation", error);
				return 0;
			}
		}

		item_name = SItemGetName(itr, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SItemGetName\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}

		add_info(info, item_start, item_end, item_name, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"add_info\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}

		prev_end = item_end;
		itr = SItemNext(itr, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SItemNext\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}
	}

	if (!s_float_equal(item_end, end_time))
	{
		add_info(info, item_end, end_time, "SIL", error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"add_info\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			return 0;
		}
	}

	l_size = SListSize(info, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SListSize\" failed"))
	{
		S_DELETE(info, "write_relation", error);
		return 0;
	}

	/* tier intervals */
	s_asprintf(&buff, error, tier_intervals, l_size);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_asprintf\" failed"))
	{
		S_DELETE(info, "write_relation", error);
		return 0;
	}

	str_size = s_strsize(buff, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"s_strsize\" failed"))
	{
		S_FREE(buff);
		S_DELETE(info, "write_relation", error);
		return 0;
	}

	SDatasourceWrite(ds, buff, sizeof(char), str_size, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"SDatasourceWrite\" failed"))
	{
		S_FREE(buff);
		S_DELETE(info, "write_relation", error);
		return 0;
	}

	S_FREE(buff);

	litr = S_ITERATOR_GET(info, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "write_relation",
				  "Call to \"S_ITERATOR_GET\" failed"))
	{
		S_DELETE(info, "write_relation", error);
		return 0;
	}

	for (counter = 1; litr != NULL; litr = SIteratorNext(litr), counter++)
	{
		SList *itemList;
		SObject *tmp;
		char *name;


		itemList = S_LIST(SIteratorObject(litr, error));
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SIteratorObject\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			return 0;
		}

		tmp = SListPop(itemList, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SIteratorObject\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			return 0;
		}

		item_name = SObjectGetString(tmp, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SObjectGetString\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_DELETE(tmp, "write_relation", error);
			return 0;
		}

		name = s_strdup(item_name, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"s_strdup\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_DELETE(tmp, "write_relation", error);
			return 0;
		}

		S_DELETE(tmp, "write_relation", error);

		tmp = SListPop(itemList, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SIteratorObject\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		item_end = SObjectGetFloat(tmp, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SObjectGetFloat\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_DELETE(tmp, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		S_DELETE(tmp, "write_relation", error);

		tmp = SListPop(itemList, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SIteratorObject\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		item_start = SObjectGetFloat(tmp, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SObjectGetFloat\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_DELETE(tmp, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		S_DELETE(tmp, "write_relation", error);

		/* tier item */
		s_asprintf(&buff, error, tier_item, counter, item_start, item_end, name);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"s_asprintf\" failed"))
		{
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		str_size = s_strsize(buff, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"s_strsize\" failed"))
		{
			S_FREE(buff);
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		SDatasourceWrite(ds, buff, sizeof(char), str_size, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "write_relation",
					  "Call to \"SDatasourceWrite\" failed"))
		{
			S_FREE(buff);
			S_DELETE(info, "write_relation", error);
			S_DELETE(litr, "write_relation", error);
			S_FREE(name);
			return 0;
		}

		S_FREE(buff);
		S_FREE(name);
	}

	S_DELETE(info, "write_relation", error);
	return num_tiers;
}
Пример #15
0
int
whois_main(int argc, char *argv[])
{
	const char *country, *host;
	char *qnichost;
	int ch, flags, use_qnichost;

#ifdef	SOCKS
	SOCKSinit(argv[0]);
#endif

	country = host = qnichost = NULL;
	flags = use_qnichost = 0;
	optind = 1; // initialize for getopt
	while ((ch = getopt(argc, argv, "aAbc:dgh:iIlmp:QrR6")) != -1) {
		switch (ch) {
		case 'a':
			host = ANICHOST;
			break;
		case 'A':
			host = PNICHOST;
			break;
		case 'b':
			host = ABUSEHOST;
			break;
		case 'c':
			country = optarg;
			break;
		case 'd':
			host = DNICHOST;
			break;
		case 'g':
			host = GNICHOST;
			break;
		case 'h':
			host = optarg;
			break;
		case 'i':
			host = INICHOST;
			break;
		case 'I':
			host = IANAHOST;
			break;
		case 'l':
			host = LNICHOST;
			break;
		case 'm':
			host = MNICHOST;
			break;
		case 'p':
			port = optarg;
			break;
		case 'Q':
			flags |= WHOIS_QUICK;
			break;
		case 'r':
			host = RNICHOST;
			break;
		case 'R':
			warnx("-R is deprecated; use '-c ru' instead");
			country = "ru";
			break;
		case '6':
			host = SNICHOST;
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (!argc || (country != NULL && host != NULL))
		usage();

	/*
	 * If no host or country is specified determine the top level domain
	 * from the query.  If the TLD is a number, query ARIN.  Otherwise, use 
	 * TLD.whois-server.net.  If the domain does not contain '.', fall
	 * back to NICHOST.
	 */
	if (host == NULL && country == NULL) {
		use_qnichost = 1;
		host = NICHOST;
		if (!(flags & WHOIS_QUICK))
			flags |= WHOIS_RECURSE;
	}
	while (argc-- > 0) {
		if (country != NULL) {
			s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL);
			whois(*argv, qnichost, flags);
		} else if (use_qnichost)
			if ((qnichost = choose_server(*argv)) != NULL)
				whois(*argv, qnichost, flags);
		if (qnichost == NULL)
			whois(*argv, host, flags);
		free(qnichost);
		qnichost = NULL;
		argv++;
	}
	exit(0);
	return 0;
}
Пример #16
0
int
main(int argc, char *argv[])
{
	const char *country, *host;
	int ch, flags;

#ifdef	SOCKS
	SOCKSinit(argv[0]);
#endif

	country = host = NULL;
	flags = 0;
	while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:PQrRS")) != -1) {
		switch (ch) {
		case 'a':
			host = ANICHOST;
			break;
		case 'A':
			host = PNICHOST;
			break;
		case 'b':
			host = ABUSEHOST;
			break;
		case 'c':
			country = optarg;
			break;
		case 'f':
			host = FNICHOST;
			break;
		case 'g':
			host = GNICHOST;
			break;
		case 'h':
			host = optarg;
			break;
		case 'i':
			host = INICHOST;
			break;
		case 'I':
			host = IANAHOST;
			break;
		case 'k':
			host = KNICHOST;
			break;
		case 'l':
			host = LNICHOST;
			break;
		case 'm':
			host = MNICHOST;
			break;
		case 'p':
			port = optarg;
			break;
		case 'P':
			host = PDBHOST;
			break;
		case 'Q':
			flags |= WHOIS_QUICK;
			break;
		case 'r':
			host = RNICHOST;
			break;
		case 'R':
			flags |= WHOIS_RECURSE;
			break;
		case 'S':
			flags |= WHOIS_SPAM_ME;
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (!argc || (country != NULL && host != NULL))
		usage();

	/*
	 * If no host or country is specified, rely on referrals from IANA.
	 */
	if (host == NULL && country == NULL) {
		if ((host = getenv("WHOIS_SERVER")) == NULL &&
		    (host = getenv("RA_SERVER")) == NULL) {
			if (!(flags & WHOIS_QUICK))
				flags |= WHOIS_RECURSE;
		}
	}
	while (argc-- > 0) {
		if (country != NULL) {
			char *qnichost;
			s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL);
			whois(*argv, qnichost, flags);
			free(qnichost);
		} else
			whois(*argv, host != NULL ? host :
			      choose_server(*argv), flags);
		argv++;
	}
	exit(0);
}
Пример #17
0
static void
whois(const char *query, const char *hostname, int flags)
{
	FILE *fp;
	struct addrinfo *hostres, *res;
	char *buf, *host, *nhost, *p;
	int s = -1, f;
	nfds_t i, j;
	size_t len, count;
	struct pollfd *fds;
	int timeout = 180;

	hostres = gethostinfo(hostname, 1);
	for (res = hostres, count = 0; res; res = res->ai_next)
		count++;
	fds = calloc(count, sizeof(*fds));
	if (fds == NULL)
		err(EX_OSERR, "calloc()");

	/*
	 * Traverse the result list elements and make non-block
	 * connection attempts.
	 */
	count = i = 0;
	for (res = hostres; res != NULL; res = res->ai_next) {
		s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
		    res->ai_protocol);
		if (s < 0)
			continue;
		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
			if (errno == EINPROGRESS) {
				/* Add the socket to poll list */
				fds[i].fd = s;
				fds[i].events = POLLERR | POLLHUP |
						POLLIN | POLLOUT;
				count++;
				i++;
			} else {
				close(s);
				s = -1;

				/*
				 * Poll only if we have something to poll,
				 * otherwise just go ahead and try next
				 * address
				 */
				if (count == 0)
					continue;
			}
		} else
			goto done;

		/*
		 * If we are at the last address, poll until a connection is
		 * established or we failed all connection attempts.
		 */
		if (res->ai_next == NULL)
			timeout = INFTIM;

		/*
		 * Poll the watched descriptors for successful connections:
		 * if we still have more untried resolved addresses, poll only
		 * once; otherwise, poll until all descriptors have errors,
		 * which will be considered as ETIMEDOUT later.
		 */
		do {
			int n;

			n = poll(fds, i, timeout);
			if (n == 0) {
				/*
				 * No event reported in time.  Try with a
				 * smaller timeout (but cap at 2-3ms)
				 * after a new host have been added.
				 */
				if (timeout >= 3)
					timeout <<= 1;

				break;
			} else if (n < 0) {
				/*
				 * errno here can only be EINTR which we would
				 * want to clean up and bail out.
				 */
				s = -1;
				goto done;
			}

			/*
			 * Check for the event(s) we have seen.
			 */
			for (j = 0; j < i; j++) {
				if (fds[j].fd == -1 || fds[j].events == 0 ||
				    fds[j].revents == 0)
					continue;
				if (fds[j].revents & ~(POLLIN | POLLOUT)) {
					close(s);
					fds[j].fd = -1;
					fds[j].events = 0;
					count--;
					continue;
				} else if (fds[j].revents & (POLLIN | POLLOUT)) {
					/* Connect succeeded. */
					s = fds[j].fd;

					goto done;
				}

			}
		} while (timeout == INFTIM && count != 0);
	}

	/* All attempts were failed */
	s = -1;
	if (count == 0)
		errno = ETIMEDOUT;
done:
	if (s == -1)
		err(EX_OSERR, "connect()");

	/* Close all watched fds except the succeeded one */
	for (j = 0; j < i; j++)
		if (fds[j].fd != s && fds[j].fd != -1)
			close(fds[j].fd);
	free(fds);

	/* Restore default blocking behavior.  */
	if ((f = fcntl(s, F_GETFL)) == -1)
		err(EX_OSERR, "fcntl()");
	f &= ~O_NONBLOCK;
	if (fcntl(s, F_SETFL, f) == -1)
		err(EX_OSERR, "fcntl()");

	fp = fdopen(s, "r+");
	if (fp == NULL)
		err(EX_OSERR, "fdopen()");

	if (!(flags & WHOIS_SPAM_ME) &&
	    (strcasecmp(hostname, DENICHOST) == 0 ||
	     strcasecmp(hostname, "de" QNICHOST_TAIL) == 0)) {
		const char *q;
		int idn = 0;
		for (q = query; *q != '\0'; q++)
			if (!isascii(*q))
				idn = 1;
		fprintf(fp, "-T dn%s %s\r\n", idn ? "" : ",ace", query);
	} else if (!(flags & WHOIS_SPAM_ME) &&
		   (strcasecmp(hostname, DKNICHOST) == 0 ||
		    strcasecmp(hostname, "dk" QNICHOST_TAIL) == 0))
		fprintf(fp, "--show-handles %s\r\n", query);
	else if ((flags & WHOIS_SPAM_ME) ||
		 strchr(query, ' ') != NULL)
		fprintf(fp, "%s\r\n", query);
	else if (strcasecmp(hostname, ANICHOST) == 0) {
		if (strncasecmp(query, "AS", 2) == 0 &&
		    strspn(query+2, "0123456789") == strlen(query+2))
			fprintf(fp, "+ a %s\r\n", query+2);
		else
			fprintf(fp, "+ %s\r\n", query);
	} else if (strcasecmp(hostres->ai_canonname, VNICHOST) == 0)
		fprintf(fp, "domain %s\r\n", query);
	else
		fprintf(fp, "%s\r\n", query);
	fflush(fp);

	nhost = NULL;
	while ((buf = fgetln(fp, &len)) != NULL) {
		/* Nominet */
		if (!(flags & WHOIS_SPAM_ME) &&
		    len == 5 && strncmp(buf, "-- \r\n", 5) == 0)
			break;

		printf("%.*s", (int)len, buf);

		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
			for (i = 0; whois_referral[i].prefix != NULL; i++) {
				p = buf;
				SCAN(p, buf+len, *p == ' ');
				if (strncasecmp(p, whois_referral[i].prefix,
					           whois_referral[i].len) != 0)
					continue;
				p += whois_referral[i].len;
				SCAN(p, buf+len, *p == ' ');
				host = p;
				SCAN(p, buf+len, ishost(*p));
				/* avoid loops */
				if (strncmp(hostname, host, p - host) != 0)
					s_asprintf(&nhost, "%.*s",
						   (int)(p - host), host);
				break;
			}
			for (i = 0; actually_arin[i] != NULL; i++) {
				if (strncmp(buf, actually_arin[i], len) == 0) {
					s_asprintf(&nhost, "%s", ANICHOST);
					break;
				}
			}
		}
		/* Verisign etc. */
		if (!(flags & WHOIS_SPAM_ME) &&
		    len >= sizeof(CHOPSPAM)-1 &&
		    (strncasecmp(buf, CHOPSPAM, sizeof(CHOPSPAM)-1) == 0 ||
		     strncasecmp(buf, CHOPSPAM+4, sizeof(CHOPSPAM)-5) == 0)) {
			printf("\n");
			break;
		}
	}
	fclose(fp);
	freeaddrinfo(hostres);
	if (nhost != NULL) {
		whois(query, nhost, flags);
		free(nhost);
	}
}
Пример #18
0
static void
whois(const char *query, const char *hostname, int flags)
{
	FILE *sfi, *sfo;
	struct addrinfo *hostres, *res;
	char *buf, *host, *nhost, *p;
	int s = -1, f;
	nfds_t i, j;
	size_t c, len, count;
	struct pollfd *fds;
	int timeout = 180;

	hostres = gethostinfo(hostname, 1);
	for (res = hostres, count = 0; res; res = res->ai_next)
		count++;

	fds = calloc(count, sizeof(*fds));
	if (fds == NULL)
		err(EX_OSERR, "calloc()");

	/*
	 * Traverse the result list elements and make non-block
	 * connection attempts.
	 */
	count = i = 0;
	for (res = hostres; res != NULL; res = res->ai_next) {
		s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
		    res->ai_protocol);
		if (s < 0)
			continue;
		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
			if (errno == EINPROGRESS) {
				/* Add the socket to poll list */
				fds[i].fd = s;
				fds[i].events = POLLERR | POLLHUP |
						POLLIN | POLLOUT;
				count++;
				i++;
			} else {
				close(s);
				s = -1;

				/*
				 * Poll only if we have something to poll,
				 * otherwise just go ahead and try next
				 * address
				 */
				if (count == 0)
					continue;
			}
		} else
			goto done;

		/*
		 * If we are at the last address, poll until a connection is
		 * established or we failed all connection attempts.
		 */
		if (res->ai_next == NULL)
			timeout = INFTIM;

		/*
		 * Poll the watched descriptors for successful connections:
		 * if we still have more untried resolved addresses, poll only
		 * once; otherwise, poll until all descriptors have errors,
		 * which will be considered as ETIMEDOUT later.
		 */
		do {
			int n;

			n = poll(fds, i, timeout);
			if (n == 0) {
				/*
				 * No event reported in time.  Try with a
				 * smaller timeout (but cap at 2-3ms)
				 * after a new host have been added.
				 */
				if (timeout >= 3)
					timeout <<= 1;

				break;
			} else if (n < 0) {
				/*
				 * errno here can only be EINTR which we would want
				 * to clean up and bail out.
				 */
				s = -1;
				goto done;
			}

			/*
			 * Check for the event(s) we have seen.
			 */
			for (j = 0; j < i; j++) {
				if (fds[j].fd == -1 || fds[j].events == 0 ||
				    fds[j].revents == 0)
					continue;
				if (fds[j].revents & ~(POLLIN | POLLOUT)) {
					close(s);
					fds[j].fd = -1;
					fds[j].events = 0;
					count--;
					continue;
				} else if (fds[j].revents & (POLLIN | POLLOUT)) {
					/* Connect succeeded. */
					s = fds[j].fd;

					goto done;
				}

			}
		} while (timeout == INFTIM && count != 0);
	}

	/* All attempts were failed */
	s = -1;
	if (count == 0)
		errno = ETIMEDOUT;

done:
	/* Close all watched fds except the succeeded one */
	for (j = 0; j < i; j++)
		if (fds[j].fd != s && fds[j].fd != -1)
			close(fds[j].fd);

	if (s != -1) {
                /* Restore default blocking behavior.  */
                if ((f = fcntl(s, F_GETFL)) != -1) {
                        f &= ~O_NONBLOCK;
                        if (fcntl(s, F_SETFL, f) == -1)
                                err(EX_OSERR, "fcntl()");
                } else
			err(EX_OSERR, "fcntl()");
        }

	free(fds);
	freeaddrinfo(hostres);
	if (s == -1)
		err(EX_OSERR, "connect()");

	sfi = fdopen(s, "r");
	sfo = fdopen(s, "w");
	if (sfi == NULL || sfo == NULL)
		err(EX_OSERR, "fdopen()");
	if (strcmp(hostname, GERMNICHOST) == 0) {
		fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
	} else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) {
		fprintf(sfo, "--show-handles %s\r\n", query);
	} else {
		fprintf(sfo, "%s\r\n", query);
	}
	fflush(sfo);
	nhost = NULL;
	while ((buf = fgetln(sfi, &len)) != NULL) {
		while (len > 0 && isspace((unsigned char)buf[len - 1]))
			buf[--len] = '\0';
		printf("%.*s\n", (int)len, buf);

		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
			host = strnstr(buf, WHOIS_SERVER_ID, len);
			if (host != NULL) {
				host += sizeof(WHOIS_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				     (int)(buf + len - host), host);
			} else if ((host =
			    strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
				host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				    (int)(buf + len - host), host);
			} else if (strcmp(hostname, ANICHOST) == 0) {
				for (c = 0; c <= len; c++)
					buf[c] = tolower((unsigned char)buf[c]);
				for (i = 0; ip_whois[i] != NULL; i++) {
					if (strnstr(buf, ip_whois[i], len) !=
					    NULL) {
						s_asprintf(&nhost, "%s",
						    ip_whois[i]);
						break;
					}
				}
			}
		}
	}
	if (nhost != NULL) {
		whois(query, nhost, 0);
		free(nhost);
	}
}
Пример #19
0
char *sosc_get_config_directory() {
	return s_asprintf("%s/Library/Preferences/org.monome.serialosc",
					  getenv("HOME"));
}
Пример #20
0
/* /B:b1-b2-b3@b4-b5&b6-b7#b8-b9$b10-b11!b12-b13;b14-b15|b16
 *
 * b1 whether the current syllable stressed or not (0: not stressed, 1: stressed)
 * b2 whether the current syllable accented or not (0: not accented, 1: accented)
 * b3 the number of phonemes in the current syllable
 * b4 position of the current syllable in the current word (forward)
 * b5 position of the current syllable in the current word (backward)
 * b6 position of the current syllable in the current phrase (forward)
 * b7 position of the current syllable in the current phrase (backward)
 * b8 the number of stressed syllables before the current syllable in the current phrase
 * b9 the number of stressed syllables after the current syllable in the current phrase
 * b10 the number of accented syllables before the current syllable in the current phrase
 * b11 the number of accented syllables after the current syllable in the current phrase
 * b12 the number of syllables from the previous stressed syllable to the current syllable
 * b13 the number of syllables from the current syllable to the next stressed syllable
 * b14 the number of syllables from the previous accented syllable to the current syllable
 * b15 the number of syllables from the current syllable to the next accented syllable
 * b16 name of the vowel of the current syllable
 */
static char *create_B_context(const SItem *item, s_erc *error)
{
	SObject *dFeat;
	char *b_context;
	sint32 b3;
	sint32 b4;
	sint32 b5;
	sint32 b6;
	sint32 b7;
	const char *b16;


	S_CLR_ERR(error);

	/* no stress/accented methods */

	/* b3 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_num_phones",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b3 = SObjectGetInt(dFeat, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_B_context", error);
	}
	else
	{
		b3 = 0;
	}

	/* b4 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_pos_word",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b4 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_B_context", error);
	}
	else
	{
		b4 = 0;
	}


	/* b5 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_pos_word_rev",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b5 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_B_context", error);
	}
	else
	{
		b5 = 0;
	}


	/* b6 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_pos_phrase",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b6 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_B_context", error);
	}
	else
	{
		b6 = 0;
	}


	/* b7 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_pos_phrase_rev",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b7 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_B_context", error);
	}
	else
	{
		b7 = 0;
	}

	/* no stress/accented methods */

	/* b16 */
	dFeat = SItemPathToFeatProc(item, "R:SylStructure.parent.R:Syllable.syllable_vowel",
							   error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		b16 = SObjectGetString(dFeat, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_B_context",
					  "Call to \"SObjectGetString\" failed"))
			return NULL;

	}
	else
	{
		b16 = "novowel";
	}

	/* we currently cannot compute b1, b2, b8, b9, b10, b11, b12, b13, b14 and b15 */
	s_asprintf(&b_context, error, "/B:0-0-%d@%d-%d&%d-%d#x-x$x-x!x-x;x-x|%s",
			   b3, b4, b5, b6, b7, b16);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_B_context",
				  "Call to \"s_asprintf\" failed"))
	{
		S_DELETE(dFeat, "create_B_context", error);
		return NULL;
	}

	S_DELETE(dFeat, "create_B_context", error);
	return b_context;
}
Пример #21
0
/* p6_p7
 *
 * p6 position of the current phoneme identity in the current syllable (forward)
 * p7 position of the current phoneme identity in the current syllable (backward)
 */
static char *create_syl_context(const SItem *item, s_erc *error)
{
	SObject *dFeat;
	char *syl_context;
	sint32 p6;
	sint32 p7;


	S_CLR_ERR(error);

	/* p6 */
	dFeat = SItemPathToFeatProc(item, "segment_pos_syl", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_syl_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		p6 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_syl_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_syl_context", error);
	}
	else
	{
		p6 = 0;
	}

	/* p7 */
	dFeat = SItemPathToFeatProc(item, "segment_pos_syl_rev", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_syl_context",
				  "Call to \"SItemPathToFeatProc\" failed"))
		return NULL;

	if (dFeat != NULL)
	{
		p7 = SObjectGetInt(dFeat, error) + 1; /* it seems as if HTS likes indexing from 1 */
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_syl_context",
					  "Call to \"SObjectGetInt\" failed"))
			return NULL;

		S_DELETE(dFeat, "create_syl_context", error);
	}
	else
	{
		p7 = 0;
	}

	s_asprintf(&syl_context, error, "%d_%d", p6, p7);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_syl_context",
				  "Call to \"s_asprintf\" failed"))
		return NULL;

	return syl_context;
}
Пример #22
0
/* p1^p2-p3+p4=p5@
 *
 * p1 the phoneme identity before the previous phoneme
 * p2 the previous phoneme identity
 * p3 the current phoneme identity
 * p4 the next phoneme identity
 * p5 the phoneme after the next phoneme identity
 */
static char *create_phone_context(const SItem *item, s_erc *error)
{
	char *p_context;
	char p1[MAX_PHONE_NAME_LENGTH] = "";
	char p2[MAX_PHONE_NAME_LENGTH] = "";
	char p3[MAX_PHONE_NAME_LENGTH] = "";
	char p4[MAX_PHONE_NAME_LENGTH] = "";
	char p5[MAX_PHONE_NAME_LENGTH] = "";
	const SObject *featPath;
	const char *tmp;


	S_CLR_ERR(error);

	/* p1 = p.p.name */
	featPath = SItemPathToFeature(item, "p.p.name", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"SItemPathToFeature\" failed"))
		return NULL;

	if (featPath != NULL)
	{
		s_strcpy(p1, SObjectGetString(featPath, error), error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy/SObjectGetString\" failed"))
			return NULL;
	}
	else
	{
		s_strcpy(p1, none_string, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}

	/* p2 = p.name */
	featPath = SItemPathToFeature(item, "p.name", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"SItemPathToFeature\" failed"))
		return NULL;

	if (featPath != NULL)
	{
		s_strcpy(p2, SObjectGetString(featPath, error), error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy/SObjectGetString\" failed"))
			return NULL;
	}
	else
	{
		s_strcpy(p2, none_string, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}

	/* p3 = name */
	tmp = SItemGetName(item, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"SItemGetName\" failed"))
		return NULL;

	if (tmp != NULL)
	{
		s_strcpy(p3, tmp, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}
	else
	{
		s_strcpy(p3, none_string, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}

	/* p4 = n.name */
	featPath = SItemPathToFeature(item, "n.name", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"SItemPathToFeature\" failed"))
		return NULL;

	if (featPath != NULL)
	{
		s_strcpy(p4, SObjectGetString(featPath, error), error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy/SObjectGetString\" failed"))
			return NULL;
	}
	else
	{
		s_strcpy(p4, none_string, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}

	/* p5 = n.n.name */
	featPath = SItemPathToFeature(item, "n.n.name", error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"SItemPathToFeature\" failed"))
		return NULL;

	if (featPath != NULL)
	{
		s_strcpy(p5, SObjectGetString(featPath, error), error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy/SObjectGetString\" failed"))
			return NULL;
	}
	else
	{
		s_strcpy(p5, none_string, error);
		if (S_CHK_ERR(error, S_CONTERR,
					  "create_phone_context",
					  "Call to \"s_strcpy\" failed"))
			return NULL;
	}

	s_asprintf(&p_context, error, "%s^%s-%s+%s=%s@", p1, p2, p3, p4, p5);
	if (S_CHK_ERR(error, S_CONTERR,
				  "create_phone_context",
				  "Call to \"s_asprintf\" failed"))
		return NULL;

	return p_context;
}