Example #1
0
File: glue.c Project: hharte/c3270
void
parse_xrm(const char *arg, const char *where)
{
	const char *name;
	unsigned rnlen;
	const char *s;
	int i;
	char *t;
	void *address = NULL;
	enum resource_type type = XRM_STRING;
	Boolean quoted;
	char c;
#if defined(C3270) /*[*/
	char *hide;
	Boolean arbitrary = False;
#endif /*]*/

	/* Validate and split. */
	if (validate_and_split_resource(where, arg, &name, &rnlen, &s) < 0)
	    	return;

	/* Look up the name. */
	for (i = 0; resources[i].name != CN; i++) {
		if (!strncapcmp(resources[i].name, name, rnlen)) {
			address = resources[i].address;
			type = resources[i].type;
			break;
		}
	}
	if (address == NULL) {
		for (i = 0; toggle_names[i].name != NULL; i++) {
			if (!strncapcmp(toggle_names[i].name, name, rnlen)) {
				address =
				    &appres.toggle[toggle_names[i].index].value;
				type = XRM_BOOLEAN;
				break;
			}
		}
	}
	/* XXX: This needs to work for s3270, too. */
#if defined(C3270) /*[*/
	if (address == NULL && valid_explicit(name, rnlen) == 0) {
		/*
		 * Handle resources that are accessed only via get_resource().
		 */
		address = &hide;
		type = XRM_STRING;
		arbitrary = True;
	}
#endif /*]*/
	if (address == NULL) {
		xs_warning("%s: Unknown resource name: %.*s",
		    where, (int)rnlen, name);
		return;
	}
	switch (type) {
	case XRM_BOOLEAN:
		if (!strcasecmp(s, "true") ||
		    !strcasecmp(s, "t") ||
		    !strcmp(s, "1")) {
			*(Boolean *)address = True;
		} else if (!strcasecmp(s, "false") ||
		    !strcasecmp(s, "f") ||
		    !strcmp(s, "0")) {
			*(Boolean *)address = False;
		} else {
			xs_warning("%s: Invalid Boolean value: %s", where, s);
			*(Boolean *)address = False;
		}
		break;
	case XRM_STRING:
		t = Malloc(strlen(s) + 1);
		*(char **)address = t;
		quoted = False;
#if defined(WC3270) /*[*/
		/*
		 * Hack to allow unquoted UNC-path printer names from older
		 * versions of the Session Wizard to continue to work, even
		 * though the rules now require quoted backslashes in resource
		 * values.
		 */
		if (!strncapcmp(ResPrinterName, name, rnlen) &&
		    s[0] == '\\' &&
		    s[1] == '\\' &&
		    s[2] != '\\' &&
		    strchr(s + 2, '\\') != NULL) {
			strcpy(t, s);
			break;
		}
#endif /*]*/

		while ((c = *s++) != '\0') {
			if (quoted) {
				switch (c) {
				case 'b':
					*t++ = '\b';
					break;
				case 'f':
					*t++ = '\f';
					break;
				case 'n':
					*t++ = '\n';
					break;
				case 'r':
					*t++ = '\r';
					break;
				case 't':
					*t++ = '\t';
					break;
				case '\\':
					/* Quote the backslash. */
					*t++ = '\\';
					break;
				default:
					/* Eat the backslash. */
					*t++ = c;
					break;
				}
				quoted = False;
			} else if (c == '\\') {
				quoted = True;
			} else {
				*t++ = c;
			}
		}
		*t = '\0';
		break;
	case XRM_INT: {
		long n;
		char *ptr;

		n = strtol(s, &ptr, 0);
		if (*ptr != '\0') {
			xs_warning("%s: Invalid Integer value: %s", where, s);
		} else {
			*(int *)address = (int)n;
		}
		break;
		}
	}

#if defined(C3270) /*[*/
	/* Add a new, arbitrarily-named resource. */
	if (arbitrary) {
		char *rsname;

		rsname = Malloc(rnlen + 1);
		(void) strncpy(rsname, name, rnlen);
		rsname[rnlen] = '\0';
		add_resource(rsname, hide);
	}
#endif /*]*/
}
Example #2
0
void
parse_xrm(const char *arg, const char *where)
{
	static char me_dot[] = ME ".";
	static char me_star[] = ME "*";
	unsigned match_len;
	const char *s;
	unsigned rnlen;
	int i;
	char *t;
	void *address = NULL;
	enum resource_type type = XRM_STRING;
#if defined(C3270) /*[*/
	char *add_buf = CN;
	char *hide;
	Boolean arbitrary = False;
#endif /*]*/

	/* Enforce "-3270." or "-3270*" or "*". */
	if (!strncmp(arg, me_dot, sizeof(me_dot)-1))
		match_len = sizeof(me_dot)-1;
	else if (!strncmp(arg, me_star, sizeof(me_star)-1))
		match_len = sizeof(me_star)-1;
	else if (arg[0] == '*')
		match_len = 1;
	else {
		xs_warning("%s: Invalid resource syntax '%.*s', name must "
		    "begin with '%s'",
		    where, (int) sizeof(me_dot)-1, arg, me_dot);
		return;
	}

	/* Separate the parts. */
	s = arg + match_len;
	while (*s && *s != ':' && !isspace(*s))
		s++;
	rnlen = s - (arg + match_len);
	if (!rnlen) {
		xs_warning("%s: Invalid resource syntax, missing resource "
		    "name", where);
		return;
	}
	while (isspace(*s))
		s++;
	if (*s != ':') {
		xs_warning("%s: Invalid resource syntax, missing ':'", where);
		return;
	}
	s++;
	while (isspace(*s))
		s++;

	/* Look up the name. */
	for (i = 0; resources[i].name != CN; i++) {
		if (!strncapcmp(resources[i].name, arg + match_len, rnlen)) {
			address = resources[i].address;
			type = resources[i].type;
#if defined(C3270) /*[*/
			if (address == NULL) {
				add_buf = Malloc(strlen(s) + 1);
				address = add_buf;
			}
#endif /*]*/
			break;
		}
	}

#if defined(C3270) /*[*/
	if (address == NULL) {
		if (!strncasecmp(ResKeymap ".", arg + match_len,
		                 strlen(ResKeymap ".")) ||
		    !strncasecmp(ResCharset ".", arg + match_len,
		                 strlen(ResCharset ".")) ||
		    !strncasecmp(ResDisplayCharset ".", arg + match_len,
		                 strlen(ResDisplayCharset ".")) ||
		    !strncasecmp(ResCodepage ".", arg + match_len,
		                 strlen(ResCodepage ".")) ||
		    !strncasecmp("host.", arg + match_len, 5) ||
		    !strncasecmp("printer.", arg + match_len, 8) ||
#if defined(_WIN32) /*[*/
		    !strncasecmp(ResHostColorFor, arg + match_len,
			    strlen(ResHostColorFor)) ||
		    !strncasecmp(ResConsoleColorForHostColor, arg + match_len,
			    strlen(ResConsoleColorForHostColor))
#else /*][*/
		    !strncasecmp(ResCursesColorFor, arg + match_len,
			    strlen(ResCursesColorFor))
#endif /*]*/
		    ) {
			address = &hide;
			type = XRM_STRING;
			arbitrary = True;
		}
	}
#endif /*]*/
	if (address == NULL) {
		xs_warning("%s: Unknown resource name: %.*s",
		    where, (int)rnlen, arg + match_len);
		return;
	}
	switch (type) {
	case XRM_BOOLEAN:
		if (!strcasecmp(s, "true") ||
		    !strcasecmp(s, "t") ||
		    !strcmp(s, "1")) {
			*(Boolean *)address = True;
		} else if (!strcasecmp(s, "false") ||
		    !strcasecmp(s, "f") ||
		    !strcmp(s, "0")) {
			*(Boolean *)address = False;
		} else {
			xs_warning("%s: Invalid Boolean value: %s", where, s);
		}
		break;
	case XRM_STRING:
		t = Malloc(strlen(s) + 1);
		*(char **)address = t;
		if (*s == '"') {
			Boolean quoted = False;
			char c;

			s++;
			while ((c = *s++) != '\0') {
				if (quoted) {
					switch (c) {
					case 'n':
						*t++ = '\n';
						break;
					case 'r':
						*t++ = '\r';
						break;
					case 'b':
						*t++ = '\b';
						break;
					default:
						*t++ = c;
						break;
					}
					quoted = False;
				} else if (c == '\\') {
					quoted = True;
				} else if (c == '"') {
					break;
				} else {
					*t++ = c;
				}
			}
			*t = '\0';
		} else {
			(void) strcpy(t, s);
		}
		break;
	case XRM_INT: {
		long n;
		char *ptr;

		n = strtol(s, &ptr, 0);
		if (*ptr != '\0') {
			xs_warning("%s: Invalid Integer value: %s", where, s);
		} else {
			*(int *)address = (int)n;
		}
		break;
		}
	}

#if defined(C3270) /*[*/
	/* Add a new, arbitrarily-named resource. */
	if (arbitrary) {
		char *rsname;

		rsname = Malloc(rnlen + 1);
		(void) strncpy(rsname, arg + match_len, rnlen);
		rsname[rnlen] = '\0';
		add_resource(rsname, hide);
	}
#endif /*]*/
}