cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

varhandlers.c (8258B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/ctype.h>
      3#include "spk_types.h"
      4#include "spk_priv.h"
      5#include "speakup.h"
      6
      7static struct st_var_header var_headers[] = {
      8	{ "version", VERSION, VAR_PROC, NULL, NULL },
      9	{ "synth_name", SYNTH, VAR_PROC, NULL, NULL },
     10	{ "keymap", KEYMAP, VAR_PROC, NULL, NULL },
     11	{ "silent", SILENT, VAR_PROC, NULL, NULL },
     12	{ "punc_some", PUNC_SOME, VAR_PROC, NULL, NULL },
     13	{ "punc_most", PUNC_MOST, VAR_PROC, NULL, NULL },
     14	{ "punc_all", PUNC_ALL, VAR_PROC, NULL, NULL },
     15	{ "delimiters", DELIM, VAR_PROC, NULL, NULL },
     16	{ "repeats", REPEATS, VAR_PROC, NULL, NULL },
     17	{ "ex_num", EXNUMBER, VAR_PROC, NULL, NULL },
     18	{ "characters", CHARS, VAR_PROC, NULL, NULL },
     19	{ "synth_direct", SYNTH_DIRECT, VAR_PROC, NULL, NULL },
     20	{ "caps_start", CAPS_START, VAR_STRING, spk_str_caps_start, NULL },
     21	{ "caps_stop", CAPS_STOP, VAR_STRING, spk_str_caps_stop, NULL },
     22	{ "delay_time", DELAY, VAR_TIME, NULL, NULL },
     23	{ "trigger_time", TRIGGER, VAR_TIME, NULL, NULL },
     24	{ "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL },
     25	{ "full_time", FULL, VAR_TIME, NULL, NULL },
     26	{ "flush_time", FLUSH, VAR_TIME, NULL, NULL },
     27	{ "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL },
     28	{ "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL },
     29	{ "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL },
     30	{ "bleep_time", BLEEP_TIME, VAR_TIME, &spk_bleep_time, NULL },
     31	{ "cursor_time", CURSOR_TIME, VAR_TIME, NULL, NULL },
     32	{ "punc_level", PUNC_LEVEL, VAR_NUM, &spk_punc_level, NULL },
     33	{ "reading_punc", READING_PUNC, VAR_NUM, &spk_reading_punc, NULL },
     34	{ "say_control", SAY_CONTROL, VAR_NUM, &spk_say_ctrl, NULL },
     35	{ "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &spk_say_word_ctl, NULL },
     36	{ "no_interrupt", NO_INTERRUPT, VAR_NUM, &spk_no_intr, NULL },
     37	{ "key_echo", KEY_ECHO, VAR_NUM, &spk_key_echo, NULL },
     38	{ "bell_pos", BELL_POS, VAR_NUM, &spk_bell_pos, NULL },
     39	{ "rate", RATE, VAR_NUM, NULL, NULL },
     40	{ "pitch", PITCH, VAR_NUM, NULL, NULL },
     41	{ "inflection", INFLECTION, VAR_NUM, NULL, NULL },
     42	{ "vol", VOL, VAR_NUM, NULL, NULL },
     43	{ "tone", TONE, VAR_NUM, NULL, NULL },
     44	{ "punct", PUNCT, VAR_NUM, NULL, NULL   },
     45	{ "voice", VOICE, VAR_NUM, NULL, NULL },
     46	{ "freq", FREQUENCY, VAR_NUM, NULL, NULL },
     47	{ "lang", LANG, VAR_NUM, NULL, NULL },
     48	{ "chartab", CHARTAB, VAR_PROC, NULL, NULL },
     49	{ "direct", DIRECT, VAR_NUM, NULL, NULL },
     50	{ "pause", PAUSE, VAR_STRING, spk_str_pause, NULL },
     51};
     52
     53static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
     54
     55static struct punc_var_t punc_vars[] = {
     56	{ PUNC_SOME, 1 },
     57	{ PUNC_MOST, 2 },
     58	{ PUNC_ALL, 3 },
     59	{ DELIM, 4 },
     60	{ REPEATS, 5 },
     61	{ EXNUMBER, 6 },
     62	{ -1, -1 },
     63};
     64
     65int spk_chartab_get_value(char *keyword)
     66{
     67	int value = 0;
     68
     69	if (!strcmp(keyword, "ALPHA"))
     70		value = ALPHA;
     71	else if (!strcmp(keyword, "B_CTL"))
     72		value = B_CTL;
     73	else if (!strcmp(keyword, "WDLM"))
     74		value = WDLM;
     75	else if (!strcmp(keyword, "A_PUNC"))
     76		value = A_PUNC;
     77	else if (!strcmp(keyword, "PUNC"))
     78		value = PUNC;
     79	else if (!strcmp(keyword, "NUM"))
     80		value = NUM;
     81	else if (!strcmp(keyword, "A_CAP"))
     82		value = A_CAP;
     83	else if (!strcmp(keyword, "B_CAPSYM"))
     84		value = B_CAPSYM;
     85	else if (!strcmp(keyword, "B_SYM"))
     86		value = B_SYM;
     87	return value;
     88}
     89
     90void speakup_register_var(struct var_t *var)
     91{
     92	static char nothing[2] = "\0";
     93	int i;
     94	struct st_var_header *p_header;
     95
     96	BUG_ON(!var || var->var_id < 0 || var->var_id >= MAXVARS);
     97	if (!var_ptrs[0]) {
     98		for (i = 0; i < MAXVARS; i++) {
     99			p_header = &var_headers[i];
    100			var_ptrs[p_header->var_id] = p_header;
    101			p_header->data = NULL;
    102		}
    103	}
    104	p_header = var_ptrs[var->var_id];
    105	if (p_header->data)
    106		return;
    107	p_header->data = var;
    108	switch (p_header->var_type) {
    109	case VAR_STRING:
    110		spk_set_string_var(nothing, p_header, 0);
    111		break;
    112	case VAR_NUM:
    113	case VAR_TIME:
    114		spk_set_num_var(0, p_header, E_DEFAULT);
    115		break;
    116	default:
    117		break;
    118	}
    119}
    120
    121void speakup_unregister_var(enum var_id_t var_id)
    122{
    123	struct st_var_header *p_header;
    124
    125	BUG_ON(var_id < 0 || var_id >= MAXVARS);
    126	p_header = var_ptrs[var_id];
    127	p_header->data = NULL;
    128}
    129
    130struct st_var_header *spk_get_var_header(enum var_id_t var_id)
    131{
    132	struct st_var_header *p_header;
    133
    134	if (var_id < 0 || var_id >= MAXVARS)
    135		return NULL;
    136	p_header = var_ptrs[var_id];
    137	if (!p_header->data)
    138		return NULL;
    139	return p_header;
    140}
    141
    142struct st_var_header *spk_var_header_by_name(const char *name)
    143{
    144	int i;
    145
    146	if (!name)
    147		return NULL;
    148
    149	for (i = 0; i < MAXVARS; i++) {
    150		if (strcmp(name, var_ptrs[i]->name) == 0)
    151			return var_ptrs[i];
    152	}
    153	return NULL;
    154}
    155
    156struct var_t *spk_get_var(enum var_id_t var_id)
    157{
    158	BUG_ON(var_id < 0 || var_id >= MAXVARS);
    159	BUG_ON(!var_ptrs[var_id]);
    160	return var_ptrs[var_id]->data;
    161}
    162EXPORT_SYMBOL_GPL(spk_get_var);
    163
    164struct punc_var_t *spk_get_punc_var(enum var_id_t var_id)
    165{
    166	struct punc_var_t *rv = NULL;
    167	struct punc_var_t *where;
    168
    169	where = punc_vars;
    170	while ((where->var_id != -1) && (!rv)) {
    171		if (where->var_id == var_id)
    172			rv = where;
    173		else
    174			where++;
    175	}
    176	return rv;
    177}
    178
    179/* handlers for setting vars */
    180int spk_set_num_var(int input, struct st_var_header *var, int how)
    181{
    182	int val;
    183	int *p_val = var->p_val;
    184	char buf[32];
    185	char *cp;
    186	struct var_t *var_data = var->data;
    187
    188	if (!var_data)
    189		return -ENODATA;
    190
    191	val = var_data->u.n.value;
    192	switch (how) {
    193	case E_NEW_DEFAULT:
    194		if (input < var_data->u.n.low || input > var_data->u.n.high)
    195			return -ERANGE;
    196		var_data->u.n.default_val = input;
    197		return 0;
    198	case E_DEFAULT:
    199		val = var_data->u.n.default_val;
    200		break;
    201	case E_SET:
    202		val = input;
    203		break;
    204	case E_INC:
    205		val += input;
    206		break;
    207	case E_DEC:
    208		val -= input;
    209		break;
    210	}
    211
    212	if (val < var_data->u.n.low || val > var_data->u.n.high)
    213		return -ERANGE;
    214
    215	var_data->u.n.value = val;
    216	if (var->var_type == VAR_TIME && p_val) {
    217		*p_val = msecs_to_jiffies(val);
    218		return 0;
    219	}
    220	if (p_val)
    221		*p_val = val;
    222	if (var->var_id == PUNC_LEVEL) {
    223		spk_punc_mask = spk_punc_masks[val];
    224		return 0;
    225	}
    226	if (var_data->u.n.multiplier != 0)
    227		val *= var_data->u.n.multiplier;
    228	val += var_data->u.n.offset;
    229	if (var->var_id < FIRST_SYNTH_VAR || !synth)
    230		return 0;
    231	if (synth->synth_adjust)
    232		return synth->synth_adjust(var);
    233
    234	if (!var_data->u.n.synth_fmt)
    235		return 0;
    236	if (var->var_id == PITCH)
    237		cp = spk_pitch_buff;
    238	else
    239		cp = buf;
    240	if (!var_data->u.n.out_str)
    241		sprintf(cp, var_data->u.n.synth_fmt, (int)val);
    242	else
    243		sprintf(cp, var_data->u.n.synth_fmt,
    244			var_data->u.n.out_str[val]);
    245	synth_printf("%s", cp);
    246	return 0;
    247}
    248
    249int spk_set_string_var(const char *page, struct st_var_header *var, int len)
    250{
    251	struct var_t *var_data = var->data;
    252
    253	if (!var_data)
    254		return -ENODATA;
    255	if (len > MAXVARLEN)
    256		return -E2BIG;
    257	if (!len) {
    258		if (!var_data->u.s.default_val)
    259			return 0;
    260		if (!var->p_val)
    261			var->p_val = var_data->u.s.default_val;
    262		if (var->p_val != var_data->u.s.default_val)
    263			strcpy((char *)var->p_val, var_data->u.s.default_val);
    264		return -ERESTART;
    265	} else if (var->p_val) {
    266		strcpy((char *)var->p_val, page);
    267	} else {
    268		return -E2BIG;
    269	}
    270	return 0;
    271}
    272
    273/*
    274 * spk_set_mask_bits sets or clears the punc/delim/repeat bits,
    275 * if input is null uses the defaults.
    276 * values for how: 0 clears bits of chars supplied,
    277 * 1 clears allk, 2 sets bits for chars
    278 */
    279int spk_set_mask_bits(const char *input, const int which, const int how)
    280{
    281	u_char *cp;
    282	short mask = spk_punc_info[which].mask;
    283
    284	if (how & 1) {
    285		for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++)
    286			spk_chartab[*cp] &= ~mask;
    287	}
    288	cp = (u_char *)input;
    289	if (!cp) {
    290		cp = spk_punc_info[which].value;
    291	} else {
    292		for (; *cp; cp++) {
    293			if (*cp < SPACE)
    294				break;
    295			if (mask < PUNC) {
    296				if (!(spk_chartab[*cp] & PUNC))
    297					break;
    298			} else if (spk_chartab[*cp] & B_NUM) {
    299				break;
    300			}
    301		}
    302		if (*cp)
    303			return -EINVAL;
    304		cp = (u_char *)input;
    305	}
    306	if (how & 2) {
    307		for (; *cp; cp++)
    308			if (*cp > SPACE)
    309				spk_chartab[*cp] |= mask;
    310	} else {
    311		for (; *cp; cp++)
    312			if (*cp > SPACE)
    313				spk_chartab[*cp] &= ~mask;
    314	}
    315	return 0;
    316}
    317
    318char *spk_strlwr(char *s)
    319{
    320	char *p;
    321
    322	if (!s)
    323		return NULL;
    324
    325	for (p = s; *p; p++)
    326		*p = tolower(*p);
    327	return s;
    328}
    329
    330char *spk_s2uchar(char *start, char *dest)
    331{
    332	int val;
    333
    334	/* Do not replace with kstrtoul: here we need start to be updated */
    335	val = simple_strtoul(skip_spaces(start), &start, 10);
    336	if (*start == ',')
    337		start++;
    338	*dest = (u_char)val;
    339	return start;
    340}