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 /*]*/ }
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 /*]*/ }