⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_dep.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 3 页
字号:
/* os_dep.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#if defined(HAVE_LIBGPM) && defined(HAVE_GPM_H)#define USE_GPM#endif#ifdef USE_GPM#include <gpm.h>#endif/* prototypes */int get_e(char *);void sigwinch(void *);void exec_new_links(struct terminal *, unsigned char *, unsigned char *, unsigned char *);void open_in_new_twterm(struct terminal *, unsigned char *, unsigned char *);void open_in_new_xterm(struct terminal *, unsigned char *, unsigned char *);void open_in_new_screen(struct terminal *, unsigned char *, unsigned char *);void open_in_new_vio(struct terminal *, unsigned char *, unsigned char *);void open_in_new_fullscreen(struct terminal *, unsigned char *, unsigned char *);void open_in_new_win32(struct terminal *, unsigned char *, unsigned char *);void open_in_new_be(struct terminal *, unsigned char *, unsigned char *);void open_in_new_g(struct terminal *, unsigned char *, unsigned char *);int is_safe_in_shell(unsigned char c){	return c == '@' || c == '+' || c == '-' || c == '.' || c == ',' || c == '=' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z');}int is_safe_in_url(unsigned char c){	return is_safe_in_shell(c) || c == ':' || c == '/' || c >= 0x80;}void check_shell_security(unsigned char **cmd){	unsigned char *c = *cmd;	while (*c) {		if (!is_safe_in_shell(*c)) *c = '_';		c++;	}}int check_shell_url(unsigned char *url){	while (*url) {		if (!is_safe_in_url(*url)) return -1;		url++;	}	return 0;}unsigned char *escape_path(unsigned char *path){	unsigned char *result;	size_t i;	if (strchr(path, '"')) return stracpy(path);	for (i = 0; path[i]; i++) if (!is_safe_in_url(path[i])) goto do_esc;	return stracpy(path);	do_esc:	result = stracpy("\"");	add_to_strn(&result, path);	add_to_strn(&result, "\"");	return result;}int get_e(char *env){	char *v;	if ((v = getenv(env))) return atoi(v);	return 0;}void ignore_signals(void){	signal(SIGPIPE, SIG_IGN);#ifdef SIGXFSZ	signal(SIGXFSZ, SIG_IGN);#endif}char *clipboard = NULL;#if defined(WIN32)#include <windows.h>#endif#if defined(OS2)#define INCL_MOU#define INCL_VIO#define INCL_DOSPROCESS#define INCL_DOSERRORS#define INCL_DOSMODULEMGR#define INCL_WIN#define INCL_WINCLIPBOARD#define INCL_WINSWITCHLIST#include <os2.h>#include <io.h>#include <process.h>#include <sys/video.h>#ifdef HAVE_SYS_FMUTEX_H#include <sys/builtin.h>#include <sys/fmutex.h>#endif#ifdef X2/* from xf86sup - XFree86 OS/2 support driver */#include <pty.h>#endif#endif#if defined(O_SIZE) && defined(__EMX__)int open_prealloc(char *name, int flags, int mode, off_t siz){	return open(name, flags | O_SIZE, mode, (unsigned long)siz);}void prealloc_truncate(int h, off_t siz){	ftruncate(h, siz);}#endif/* Terminal size */#ifdef WIN32/* Cygwin has a bug and loses SIGWINCH sometimes, so poll it */static void winch_thread(void *p, int l){	static int old_xsize, old_ysize;	static int cur_xsize, cur_ysize;	if (get_terminal_size(0, &old_xsize, &old_ysize)) return;	while (1) {		if (get_terminal_size(1, &cur_xsize, &cur_ysize)) return;		if ((old_xsize != cur_xsize) || (old_ysize != cur_ysize)) {			old_xsize = cur_xsize;			old_ysize = cur_ysize;			raise(SIGWINCH);		}		sleep(1);	}}static void win32_resize_poll(void){	static int winch_thread_running = 0;	if (!winch_thread_running) {		if (start_thread(winch_thread, NULL, 0) >= 0)			winch_thread_running = 1;	}}#endif#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(WIN32) || defined(SPAD)void sigwinch(void *s){	((void (*)(void))s)();}void handle_terminal_resize(int fd, void (*fn)(void)){	install_signal_handler(SIGWINCH, sigwinch, fn, 0);#ifdef WIN32	win32_resize_poll();#endif}void unhandle_terminal_resize(int fd){	install_signal_handler(SIGWINCH, NULL, NULL, 0);}int get_terminal_size(int fd, int *x, int *y){	struct winsize ws;	if (!x || !y) return -1;	if (ioctl(1, TIOCGWINSZ, &ws) != -1) {		if (!(*x = ws.ws_col) && !(*x = get_e("COLUMNS"))) *x = 80;		if (!(*y = ws.ws_row) && !(*y = get_e("LINES"))) *y = 24;		return 0;	} else {		if (!(*x = get_e("COLUMNS"))) *x = 80;		if (!(*y = get_e("LINES"))) *y = 24;	}	return 0;}#elif defined(OS2)#define A_DECL(type, var) type var##1, var##2, *var = _THUNK_PTR_STRUCT_OK(&var##1) ? &var##1 : &var##2int is_xterm(void){	static int xt = -1;	if (xt == -1) xt = !!getenv("WINDOWID");	return xt;}int winch_pipe[2];int winch_thread_running = 0;#define WINCH_SLEEPTIME 500 /* time in ms for winch thread to sleep */static void winch_thread(void){	/* A thread which regularly checks whether the size of 	   window has changed. Then raise SIGWINCH or notifiy	   the thread responsible to handle this. */	static int old_xsize, old_ysize;	static int cur_xsize, cur_ysize;	ignore_signals();	if (get_terminal_size(1, &old_xsize, &old_ysize)) return;	while (1) {		if (get_terminal_size(1, &cur_xsize, &cur_ysize)) return;		if ((old_xsize != cur_xsize) || (old_ysize != cur_ysize)) {			old_xsize = cur_xsize;			old_ysize = cur_ysize;			write(winch_pipe[1], "x", 1);			/* Resizing may take some time. So don't send a flood                     of requests?! */			_sleep2(2*WINCH_SLEEPTIME);   		}		else			_sleep2(WINCH_SLEEPTIME);	}}static void winch(void *s){	char c;	while (can_read(winch_pipe[0]) && read(winch_pipe[0], &c, 1) == 1);	((void (*)(void))s)();}void handle_terminal_resize(int fd, void (*fn)(void)){	if (!is_xterm()) return;	if (!winch_thread_running) {		if (c_pipe(winch_pipe) < 0) return;		winch_thread_running = 1;		_beginthread((void (*)(void *))winch_thread, NULL, 0x32000, NULL);	}	set_handlers(winch_pipe[0], winch, NULL, NULL, fn);}void unhandle_terminal_resize(int fd){	set_handlers(winch_pipe[0], NULL, NULL, NULL, NULL);}int get_terminal_size(int fd, int *x, int *y){	if (!x || !y) return -1;	if (is_xterm()) {#ifdef X2		/* int fd; */		int arc;		struct winsize win;		/* fd = STDIN_FILENO; */		arc = ptioctl(1, TIOCGWINSZ, &win);		if (arc) {			*x = 80;			*y = 24;			return 0;		}		*y = win.ws_row;		*x = win.ws_col;		goto set_default;#else		*x = 80; *y = 24;		return 0;#endif	} else {		int a[2] = { 0, 0 };		_scrsize(a);		*x = a[0];		*y = a[1];		set_default:		if (*x == 0) {			*x = get_e("COLUMNS");			if (*x == 0) *x = 80;		}		if (*y == 0) {			*y = get_e("LINES");			if (*y == 0) *y = 24;		}	}	return 0;}#elif defined(WIN32)#endif/* Pipe */#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(SPAD)void set_bin(int fd){}int c_pipe(int *fd){	return pipe(fd);}#elif defined(OS2) || defined(WIN32)void set_bin(int fd){	setmode(fd, O_BINARY);}int c_pipe(int *fd){	int r = pipe(fd);	if (!r) set_bin(fd[0]), set_bin(fd[1]);	return r;}#endif/* Filename */int check_file_name(unsigned char *file){	return 1;		/* !!! FIXME */}/* Exec */int can_twterm(void) /* Check if it make sense to call a twterm. */{	static int xt = -1;	if (xt == -1) xt = !!getenv("TWDISPLAY");	return xt;}#if defined(UNIX) || defined(SPAD)int is_xterm(void){	static int xt = -1;	if (xt == -1) xt = getenv("DISPLAY") && *getenv("DISPLAY");	return xt;}#elif defined(BEOS) || defined(ATHEOS)int is_xterm(void){	return 0;}#elif defined(WIN32)int is_xterm(void){	static int xt = -1;	if (xt == -1) xt = !!getenv("WINDOWID");	return xt;}#elif defined(RISCOS)int is_xterm(void){       return 1;}#endiftcount resize_count = 0;void close_fork_tty(void){	struct terminal *t;	struct download *d;	struct connection *c;	struct k_conn *k;	foreach (t, terminals) if (t->fdin > 0) close(t->fdin);	foreach (d, downloads) if (d->handle > 0) close(d->handle);	foreach (c, queue) close_socket(&c->sock1), close_socket(&c->sock2);	foreach (k, keepalive_connections) close(k->conn);}#if defined(WIN32)void get_path_to_exe(void){	/* Standard method (argv[0]) doesn't work, if links is executed from	   symlink --- it returns symlink name and cmd.exe is unable to start	   it */	unsigned r;	static unsigned char path[4096];	r = GetModuleFileName(NULL, path, sizeof path);	if (r <= 0 || r >= sizeof path) {		path_to_exe = g_argv[0];		return;	}	path_to_exe = path;}#elif defined(OS2)void get_path_to_exe(void){	/* If you spawn links with quotation marks from cmd.exe,	   the quotation marks will be present in g_argv[0] ... and will	   prevent executing it */	static char path[270];	PPIB pib = NULL;	path_to_exe = g_argv[0];	/*if (!strchr(path_to_exe, ' ') && !strchr(path_to_exe, '"')) return;*/	DosGetInfoBlocks(NULL, &pib);	if (!pib) return;	if (DosQueryModuleName(pib->pib_hmte, sizeof path, path)) return;	path_to_exe = path;}#elsevoid get_path_to_exe(void){	path_to_exe = g_argv[0];}#endif#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(SPAD)#if defined(BEOS) && defined(HAVE_SETPGID)int exe(char *path, int fg){	pid_t p;	int s;	fg=fg;  /* ignore flag */	if (!(p = fork())) {		setpgid(0, 0);		system(path);		_exit(0);	}	if (p > 0) waitpid(p, &s, 0);	else return system(path);	return 0;}#else/* UNIX */int exe(char *path, int fg){#ifdef G	if (F && drv->exec) return drv->exec(path, fg);#endif#ifdef SIGTSTP	signal(SIGTSTP, SIG_DFL);#endif#ifdef SIGCONT	signal(SIGCONT, SIG_DFL);#endif#ifdef SIGWINCH	signal(SIGWINCH, SIG_DFL);#endif	return system(path);}#endif/* clipboard -> links */unsigned char *get_clipboard_text(struct terminal *term){#ifdef GRDRV_X	if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {		return x_get_clipboard_text();	}#endif	return stracpy(clipboard);}/* links -> clipboard */void set_clipboard_text(struct terminal *term, unsigned char *data){#ifdef GRDRV_X	if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {		x_set_clipboard_text(term->dev, data);		return;	}#endif	if (clipboard) mem_free(clipboard);	clipboard = stracpy(data);}int clipboard_support(struct terminal *term){#ifdef GRDRV_X	if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {		return 1;	}#endif	return 0;}void set_window_title(unsigned char *title){	/* !!! FIXME */}unsigned char *get_window_title(void){	/* !!! FIXME */	return NULL;}int resize_window(int x, int y){	return -1;}#elif defined(WIN32)static int is_winnt(void){	OSVERSIONINFO v;	v.dwOSVersionInfoSize = sizeof v;	if (!GetVersionEx(&v)) return 0;	return v.dwPlatformId >= VER_PLATFORM_WIN32_NT;}#define WIN32_START_STRING	"start /wait "int exe(char *path, int fg){	/* This is very tricky. We must have exactly 3 arguments, the first	   one shell and the second one "/c", otherwise Cygwin would quote	   the arguments and trash them */	int ct;	char buffer[1024];	char buffer2[1024];	pid_t pid;	unsigned char *x1;	char *arg;	x1 = GETSHELL;	if (!x1) x1 = DEFAULT_SHELL;	arg = alloca(strlen(WIN32_START_STRING) + 3 + strlen(path) + 1);	strcpy(arg, WIN32_START_STRING);	if (*path == '"' && strlen(x1) >= 7 && !strcasecmp(x1 + strlen(x1) - 7, "cmd.exe")) strcat(arg, "\"\" ");	strcat(arg, path);	ct = GetConsoleTitle(buffer, sizeof buffer);	if (!(pid = fork())) {		int i;	/* Win98 crashes if we spawn command.com and have some sockets open */		for (i = 0; i < FD_SETSIZE; i++) close(i);		open("nul", O_RDONLY);		open("nul", O_WRONLY);		open("nul", O_WRONLY);		execlp(x1, x1, "/c", arg, NULL);		_exit(1);	}	if (!is_winnt()) {		sleep(1);		if (ct && GetConsoleTitle(buffer2, sizeof buffer2) && !casecmp(buffer2, "start", 5)) {			SetConsoleTitle(buffer);		}	}	if (pid != -1) waitpid(pid, NULL, 0);	return 0;}unsigned char *get_clipboard_text(struct terminal *term){	char buffer[256];	unsigned char *str, *s, *d;	int l;	int r;	int h = open("/dev/clipboard", O_RDONLY);	if (h == -1) return stracpy(clipboard);	set_bin(h);	/* O_TEXT doesn't work on clipboard handle */	str = init_str();	l = 0;	while ((r = hard_read(h, buffer, sizeof buffer)) > 0)		add_bytes_to_str(&str, &l, buffer, r);	close(h);	for (s = str, d = str; *s; s++)		if (!(s[0] == '\r' && s[1] == '\n')) *d++ = *s;	*d = 0;	return str;}/* Putting Czech characters to clipboard doesn't work, but it should be fixed   rather in Cygwin than here */void set_clipboard_text(struct terminal *term, unsigned char *data){	unsigned char *conv_data;	int l;	int h;	if (clipboard) mem_free(clipboard);	clipboard = stracpy(data);	h = open("/dev/clipboard", O_WRONLY);	if (h == -1) return;	set_bin(h);	/* O_TEXT doesn't work on clipboard handle */	conv_data = init_str();	l = 0;	for (; *data; data++)		if (*data == '\n') add_to_str(&conv_data, &l, "\r\n");		else add_chr_to_str(&conv_data, &l, *data);	hard_write(h, conv_data, l);	mem_free(conv_data);	close(h);}int clipboard_support(struct terminal *term){	return 1;}static int get_windows_cp(void){	char str[6];	int cp, idx;	static int win_cp_idx = -1;	if (win_cp_idx != -1) return win_cp_idx;	cp = GetConsoleOutputCP();	if (cp <= 0 || cp >= 100000) return 0;	sprintf(str, "%d", cp);	if ((idx = get_cp_index(str)) < 0) return 0;	win_cp_idx = idx;	return idx;}static int get_utf8_cp(void){	static int idx = -1;	return idx >= 0 ? idx : (idx = get_cp_index("utf-8"));}void set_window_title(unsigned char *title){	unsigned char *t;	struct conv_table *ct;	if (is_xterm()) return;	ct = get_translation_table(get_utf8_cp(), get_windows_cp());	t = convert_string(ct, title, strlen(title), NULL);	SetConsoleTitle(t);	mem_free(t);}unsigned char *get_window_title(void){	struct conv_table *ct;	int r;	char buffer[1024];	if (is_xterm()) return NULL;	if (!(r = GetConsoleTitle(buffer, sizeof buffer))) return NULL;	ct = get_translation_table(get_windows_cp(), get_utf8_cp());	return convert_string(ct, buffer, r, NULL);}static void call_resize(unsigned char *x1, int x, int y){	pid_t pid;	unsigned char arg[40];	sprintf(arg, "mode %d,%d", x, y);	if (!(pid = fork())) {		int i;	/* Win98 crashes if we spawn command.com and have some sockets open */		for (i = 0; i < FD_SETSIZE; i++) if (i != 1 && i != 2) close(i);		open("nul", O_WRONLY);		execlp(x1, x1, "/c", arg, NULL);		_exit(1);	}	if (pid != -1) waitpid(pid, NULL, 0);}int resize_window(int x, int y){	int old_x, old_y;	int ct = 0, fullscreen = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -