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

util.c (5731B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <signal.h>
      3#include <stdbool.h>
      4#include <string.h>
      5#include <stdlib.h>
      6#include <sys/ttydefaults.h>
      7
      8#include "../browser.h"
      9#include "../keysyms.h"
     10#include "../helpline.h"
     11#include "../ui.h"
     12#include "../util.h"
     13#include "../libslang.h"
     14
     15static void ui_browser__argv_write(struct ui_browser *browser,
     16				   void *entry, int row)
     17{
     18	char **arg = entry;
     19	bool current_entry = ui_browser__is_current_entry(browser, row);
     20
     21	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
     22						       HE_COLORSET_NORMAL);
     23	ui_browser__write_nstring(browser, *arg, browser->width);
     24}
     25
     26static int popup_menu__run(struct ui_browser *menu, int *keyp)
     27{
     28	int key;
     29
     30	if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
     31		return -1;
     32
     33	while (1) {
     34		key = ui_browser__run(menu, 0);
     35
     36		switch (key) {
     37		case K_RIGHT:
     38		case K_ENTER:
     39			key = menu->index;
     40			break;
     41		case K_LEFT:
     42		case K_ESC:
     43		case 'q':
     44		case CTRL('c'):
     45			key = -1;
     46			break;
     47		default:
     48			if (keyp) {
     49				*keyp = key;
     50				key = menu->nr_entries;
     51				break;
     52			}
     53			continue;
     54		}
     55
     56		break;
     57	}
     58
     59	ui_browser__hide(menu);
     60	return key;
     61}
     62
     63int ui__popup_menu(int argc, char * const argv[], int *keyp)
     64{
     65	struct ui_browser menu = {
     66		.entries    = (void *)argv,
     67		.refresh    = ui_browser__argv_refresh,
     68		.seek	    = ui_browser__argv_seek,
     69		.write	    = ui_browser__argv_write,
     70		.nr_entries = argc,
     71	};
     72	return popup_menu__run(&menu, keyp);
     73}
     74
     75int ui_browser__input_window(const char *title, const char *text, char *input,
     76			     const char *exit_msg, int delay_secs)
     77{
     78	int x, y, len, key;
     79	int max_len = 60, nr_lines = 0;
     80	static char buf[50];
     81	const char *t;
     82
     83	t = text;
     84	while (1) {
     85		const char *sep = strchr(t, '\n');
     86
     87		if (sep == NULL)
     88			sep = strchr(t, '\0');
     89		len = sep - t;
     90		if (max_len < len)
     91			max_len = len;
     92		++nr_lines;
     93		if (*sep == '\0')
     94			break;
     95		t = sep + 1;
     96	}
     97
     98	pthread_mutex_lock(&ui__lock);
     99
    100	max_len += 2;
    101	nr_lines += 8;
    102	y = SLtt_Screen_Rows / 2 - nr_lines / 2;
    103	x = SLtt_Screen_Cols / 2 - max_len / 2;
    104
    105	SLsmg_set_color(0);
    106	SLsmg_draw_box(y, x++, nr_lines, max_len);
    107	if (title) {
    108		SLsmg_gotorc(y, x + 1);
    109		SLsmg_write_string((char *)title);
    110	}
    111	SLsmg_gotorc(++y, x);
    112	nr_lines -= 7;
    113	max_len -= 2;
    114	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
    115				   nr_lines, max_len, 1);
    116	y += nr_lines;
    117	len = 5;
    118	while (len--) {
    119		SLsmg_gotorc(y + len - 1, x);
    120		SLsmg_write_nstring((char *)" ", max_len);
    121	}
    122	SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
    123
    124	SLsmg_gotorc(y + 3, x);
    125	SLsmg_write_nstring((char *)exit_msg, max_len);
    126	SLsmg_refresh();
    127
    128	pthread_mutex_unlock(&ui__lock);
    129
    130	x += 2;
    131	len = 0;
    132	key = ui__getch(delay_secs);
    133	while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
    134		pthread_mutex_lock(&ui__lock);
    135
    136		if (key == K_BKSPC) {
    137			if (len == 0) {
    138				pthread_mutex_unlock(&ui__lock);
    139				goto next_key;
    140			}
    141			SLsmg_gotorc(y, x + --len);
    142			SLsmg_write_char(' ');
    143		} else {
    144			buf[len] = key;
    145			SLsmg_gotorc(y, x + len++);
    146			SLsmg_write_char(key);
    147		}
    148		SLsmg_refresh();
    149
    150		pthread_mutex_unlock(&ui__lock);
    151
    152		/* XXX more graceful overflow handling needed */
    153		if (len == sizeof(buf) - 1) {
    154			ui_helpline__push("maximum size of symbol name reached!");
    155			key = K_ENTER;
    156			break;
    157		}
    158next_key:
    159		key = ui__getch(delay_secs);
    160	}
    161
    162	buf[len] = '\0';
    163	strncpy(input, buf, len+1);
    164	return key;
    165}
    166
    167void __ui__info_window(const char *title, const char *text, const char *exit_msg)
    168{
    169	int x, y;
    170	int max_len = 0, nr_lines = 0;
    171	const char *t;
    172
    173	t = text;
    174	while (1) {
    175		const char *sep = strchr(t, '\n');
    176		int len;
    177
    178		if (sep == NULL)
    179			sep = strchr(t, '\0');
    180		len = sep - t;
    181		if (max_len < len)
    182			max_len = len;
    183		++nr_lines;
    184		if (*sep == '\0')
    185			break;
    186		t = sep + 1;
    187	}
    188
    189	max_len += 2;
    190	nr_lines += 2;
    191	if (exit_msg)
    192		nr_lines += 2;
    193	y = SLtt_Screen_Rows / 2 - nr_lines / 2,
    194	x = SLtt_Screen_Cols / 2 - max_len / 2;
    195
    196	SLsmg_set_color(0);
    197	SLsmg_draw_box(y, x++, nr_lines, max_len);
    198	if (title) {
    199		SLsmg_gotorc(y, x + 1);
    200		SLsmg_write_string((char *)title);
    201	}
    202	SLsmg_gotorc(++y, x);
    203	if (exit_msg)
    204		nr_lines -= 2;
    205	max_len -= 2;
    206	SLsmg_write_wrapped_string((unsigned char *)text, y, x,
    207				   nr_lines, max_len, 1);
    208	if (exit_msg) {
    209		SLsmg_gotorc(y + nr_lines - 2, x);
    210		SLsmg_write_nstring((char *)" ", max_len);
    211		SLsmg_gotorc(y + nr_lines - 1, x);
    212		SLsmg_write_nstring((char *)exit_msg, max_len);
    213	}
    214}
    215
    216void ui__info_window(const char *title, const char *text)
    217{
    218	pthread_mutex_lock(&ui__lock);
    219	__ui__info_window(title, text, NULL);
    220	SLsmg_refresh();
    221	pthread_mutex_unlock(&ui__lock);
    222}
    223
    224int ui__question_window(const char *title, const char *text,
    225			const char *exit_msg, int delay_secs)
    226{
    227	pthread_mutex_lock(&ui__lock);
    228	__ui__info_window(title, text, exit_msg);
    229	SLsmg_refresh();
    230	pthread_mutex_unlock(&ui__lock);
    231	return ui__getch(delay_secs);
    232}
    233
    234int ui__help_window(const char *text)
    235{
    236	return ui__question_window("Help", text, "Press any key...", 0);
    237}
    238
    239int ui__dialog_yesno(const char *msg)
    240{
    241	return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
    242}
    243
    244static int __ui__warning(const char *title, const char *format, va_list args)
    245{
    246	char *s;
    247
    248	if (vasprintf(&s, format, args) > 0) {
    249		int key;
    250
    251		key = ui__question_window(title, s, "Press any key...", 0);
    252		free(s);
    253		return key;
    254	}
    255
    256	fprintf(stderr, "%s\n", title);
    257	vfprintf(stderr, format, args);
    258	return K_ESC;
    259}
    260
    261static int perf_tui__error(const char *format, va_list args)
    262{
    263	return __ui__warning("Error:", format, args);
    264}
    265
    266static int perf_tui__warning(const char *format, va_list args)
    267{
    268	return __ui__warning("Warning:", format, args);
    269}
    270
    271struct perf_error_ops perf_tui_eops = {
    272	.error		= perf_tui__error,
    273	.warning	= perf_tui__warning,
    274};