int stristart(const char *str, const char *val, const char **ptr) { const char *p, *q; p = str; q = val; while (*q != '\0') { if (qemu_toupper(*p) != qemu_toupper(*q)) return 0; p++; q++; } if (ptr) *ptr = p; return 1; }
static int read_naa_id(const uint8_t *p, uint64_t *p_wwn) { int i; if ((p[1] & 0xF) == 3) { /* NAA designator type */ if (p[3] != 8) { return -EINVAL; } *p_wwn = ldq_be_p(p + 4); return 0; } if ((p[1] & 0xF) == 8) { /* SCSI name string designator type */ if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) { return -EINVAL; } if (p[3] > 20 && p[24] != ',') { return -EINVAL; } *p_wwn = 0; for (i = 8; i < 24; i++) { char c = qemu_toupper(p[i]); c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10); *p_wwn = (*p_wwn << 4) | c; } return 0; } return -EINVAL; }
static int64_t suffix_mul(char suffix, int64_t unit) { switch (qemu_toupper(suffix)) { case STRTOSZ_DEFSUFFIX_B: return 1; case STRTOSZ_DEFSUFFIX_KB: return unit; case STRTOSZ_DEFSUFFIX_MB: return unit * unit; case STRTOSZ_DEFSUFFIX_GB: return unit * unit * unit; case STRTOSZ_DEFSUFFIX_TB: return unit * unit * unit * unit; } return -1; }
static int64_t suffix_mul(char suffix, int64_t unit) { switch (qemu_toupper(suffix)) { case 'B': return 1; case 'K': return unit; case 'M': return unit * unit; case 'G': return unit * unit * unit; case 'T': return unit * unit * unit * unit; case 'P': return unit * unit * unit * unit * unit; case 'E': return unit * unit * unit * unit * unit * unit; } return -1; }
/* * Convert string to bytes, allowing either B/b for bytes, K/k for KB, * M/m for MB, G/g for GB or T/t for TB. Default without any postfix * is MB. End pointer will be returned in *end, if not NULL. A valid * value must be terminated by whitespace, ',' or '\0'. Return -1 on * error. */ int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) { int64_t retval = -1; char *endptr; unsigned char c, d; int mul_required = 0; double val, mul, integral, fraction; errno = 0; val = strtod(nptr, &endptr); if (isnan(val) || endptr == nptr || errno != 0) { goto fail; } fraction = modf(val, &integral); if (fraction != 0) { mul_required = 1; } /* * Any whitespace character is fine for terminating the number, * in addition we accept ',' to handle strings where the size is * part of a multi token argument. */ c = *endptr; d = c; if (qemu_isspace(c) || c == '\0' || c == ',') { c = 0; if (default_suffix) { d = default_suffix; } else { d = c; } } switch (qemu_toupper(d)) { case STRTOSZ_DEFSUFFIX_B: mul = 1; if (mul_required) { goto fail; } break; case STRTOSZ_DEFSUFFIX_KB: mul = 1 << 10; break; case 0: if (mul_required) { goto fail; } case STRTOSZ_DEFSUFFIX_MB: mul = 1ULL << 20; break; case STRTOSZ_DEFSUFFIX_GB: mul = 1ULL << 30; break; case STRTOSZ_DEFSUFFIX_TB: mul = 1ULL << 40; break; default: goto fail; } /* * If not terminated by whitespace, ',', or \0, increment endptr * to point to next character, then check that we are terminated * by an appropriate separating character, ie. whitespace, ',', or * \0. If not, we are seeing trailing garbage, thus fail. */ if (c != 0) { endptr++; if (!qemu_isspace(*endptr) && *endptr != ',' && *endptr != 0) { goto fail; } } if ((val * mul >= INT64_MAX) || val < 0) { goto fail; } retval = val * mul; fail: if (end) { *end = endptr; } return retval; }
static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table, const char *language, kbd_layout_t *k) { FILE *f; char * filename; char line[1024]; int len; filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language); f = filename ? fopen(filename, "r") : NULL; g_free(filename); if (!f) { fprintf(stderr, "Could not read keymap file: '%s'\n", language); return NULL; } if (!k) { k = g_new0(kbd_layout_t, 1); } for(;;) { if (fgets(line, 1024, f) == NULL) { break; } len = strlen(line); if (len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } if (line[0] == '#') { continue; } if (!strncmp(line, "map ", 4)) { continue; } if (!strncmp(line, "include ", 8)) { parse_keyboard_layout(table, line + 8, k); } else { char *end_of_keysym = line; while (*end_of_keysym != 0 && *end_of_keysym != ' ') { end_of_keysym++; } if (*end_of_keysym) { int keysym; *end_of_keysym = 0; keysym = get_keysym(table, line); if (keysym == 0) { /* fprintf(stderr, "Warning: unknown keysym %s\n", line);*/ } else { const char *rest = end_of_keysym + 1; int keycode = strtol(rest, NULL, 0); if (strstr(rest, "numlock")) { add_to_key_range(&k->keypad_range, keycode); add_to_key_range(&k->numlock_range, keysym); /* fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode); */ } if (strstr(rest, "shift")) { keycode |= SCANCODE_SHIFT; } if (strstr(rest, "altgr")) { keycode |= SCANCODE_ALTGR; } if (strstr(rest, "ctrl")) { keycode |= SCANCODE_CTRL; } add_keysym(line, keysym, keycode, k); if (strstr(rest, "addupper")) { char *c; for (c = line; *c; c++) { *c = qemu_toupper(*c); } keysym = get_keysym(table, line); if (keysym) { add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k); } } } } } } fclose(f); return k; }
static int parse_keyboard_layout(kbd_layout_t *k, const name2keysym_t *table, const char *language, Error **errp) { int ret; FILE *f; char * filename; char line[1024]; char keyname[64]; int len; filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language); trace_keymap_parse(filename); f = filename ? fopen(filename, "r") : NULL; g_free(filename); if (!f) { error_setg(errp, "could not read keymap file: '%s'", language); return -1; } for(;;) { if (fgets(line, 1024, f) == NULL) { break; } len = strlen(line); if (len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } if (line[0] == '#') { continue; } if (!strncmp(line, "map ", 4)) { continue; } if (!strncmp(line, "include ", 8)) { error_setg(errp, "keymap include files are not supported any more"); ret = -1; goto out; } else { int offset = 0; while (line[offset] != 0 && line[offset] != ' ' && offset < sizeof(keyname) - 1) { keyname[offset] = line[offset]; offset++; } keyname[offset] = 0; if (strlen(keyname)) { int keysym; keysym = get_keysym(table, keyname); if (keysym == 0) { /* warn_report("unknown keysym %s", line);*/ } else { const char *rest = line + offset + 1; int keycode = strtol(rest, NULL, 0); if (strstr(rest, "shift")) { keycode |= SCANCODE_SHIFT; } if (strstr(rest, "altgr")) { keycode |= SCANCODE_ALTGR; } if (strstr(rest, "ctrl")) { keycode |= SCANCODE_CTRL; } add_keysym(line, keysym, keycode, k); if (strstr(rest, "addupper")) { char *c; for (c = keyname; *c; c++) { *c = qemu_toupper(*c); } keysym = get_keysym(table, keyname); if (keysym) { add_keysym(line, keysym, keycode | SCANCODE_SHIFT, k); } } } } } } ret = 0; out: fclose(f); return ret; }