diff options
Diffstat (limited to 'redhat/tdebase/kdebase-3.5.13-tsak_keyboard_hotplug.patch')
-rw-r--r-- | redhat/tdebase/kdebase-3.5.13-tsak_keyboard_hotplug.patch | 641 |
1 files changed, 0 insertions, 641 deletions
diff --git a/redhat/tdebase/kdebase-3.5.13-tsak_keyboard_hotplug.patch b/redhat/tdebase/kdebase-3.5.13-tsak_keyboard_hotplug.patch deleted file mode 100644 index 8c8ab415f..000000000 --- a/redhat/tdebase/kdebase-3.5.13-tsak_keyboard_hotplug.patch +++ /dev/null @@ -1,641 +0,0 @@ -commit 5f413b26ebaab8a6478427e4125bda628058ff85 -Author: Timothy Pearson <kb9vqf@pearsoncomputing.net> -Date: 1327015159 -0600 - - Add keyboard hotplug (add/remove) support to tsak - This closes Bug 587 - Fix warning in kompmgr - -diff --git a/tsak/CMakeLists.txt b/tsak/CMakeLists.txt -index 6aa5b49..4490636 100644 ---- a/tsak/CMakeLists.txt -+++ b/tsak/CMakeLists.txt -@@ -23,5 +23,6 @@ link_directories( - - tde_add_executable( tsak - SOURCES main.cpp -+ LINK udev - DESTINATION ${BIN_INSTALL_DIR} - ) -diff --git a/tsak/main.cpp b/tsak/main.cpp -index 050d6c0..df485a0 100644 ---- a/tsak/main.cpp -+++ b/tsak/main.cpp -@@ -1,8 +1,8 @@ - /* - Copyright 2010 Adam Marchetti --Copyright 2011 Timothy Pearson <kb9vqf@pearsoncomputing.net> -+Copyright 2011-2012 Timothy Pearson <kb9vqf@pearsoncomputing.net> - --This file is part of tsak. -+This file is part of tsak, the TDE Secure Attention Key daemon - - tsak is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as -@@ -35,9 +35,15 @@ License along with tsak. If not, see http://www.gnu.org/licenses/. - #include <sys/time.h> - #include <termios.h> - #include <signal.h> -+#include <libudev.h> -+#include <libgen.h> - - #define FIFO_DIR "/tmp/ksocket-global" - #define FIFO_FILE_OUT "/tmp/ksocket-global/tsak" -+#define FIFO_LOCKFILE_OUT "/tmp/ksocket-global/tsak.lock" -+ -+#define MAX_KEYBOARDS 64 -+#define MAX_INPUT_NODE 128 - - #define TestBit(bit, array) (array[(bit) / 8] & (1 << ((bit) % 8))) - -@@ -46,9 +52,18 @@ typedef unsigned char byte; - bool mPipeOpen_out = false; - int mPipe_fd_out = -1; - -+int mPipe_lockfd_out = -1; -+ -+char filename[32]; -+char key_bitmask[(KEY_MAX + 7) / 8]; -+ - struct sigaction usr_action; - sigset_t block_mask; - -+int keyboard_fd_num; -+int keyboard_fds[MAX_KEYBOARDS]; -+int child_pids[MAX_KEYBOARDS]; -+ - const char *keycode[256] = - { - "", "<esc>", "1", "2", "3", "4", "5", "6", "7", "8", -@@ -79,6 +94,26 @@ int bit_set(size_t i, const byte* a) - return a[i/CHAR_BIT] & (1 << i%CHAR_BIT); - } - -+// -------------------------------------------------------------------------------------- -+// Useful function from Stack Overflow -+// http://stackoverflow.com/questions/874134/find-if-string-endswith-another-string-in-c -+// -------------------------------------------------------------------------------------- -+/* returns 1 iff str ends with suffix */ -+int str_ends_with(const char * str, const char * suffix) { -+ -+ if( str == NULL || suffix == NULL ) -+ return 0; -+ -+ size_t str_len = strlen(str); -+ size_t suffix_len = strlen(suffix); -+ -+ if(suffix_len > str_len) -+ return 0; -+ -+ return 0 == strncmp( str + str_len - suffix_len, suffix, suffix_len ); -+} -+// -------------------------------------------------------------------------------------- -+ - /* Assign features (supported axes and keys) of the physical input device (devin) - * to the virtual input device (devout) */ - static void copy_features(int devin, int devout) -@@ -111,26 +146,40 @@ static void copy_features(int devin, int devout) - } - } - --int find_keyboard() { -+int find_keyboards() { - int i, j; - int fd; -- char filename[32]; -- char key_bitmask[(KEY_MAX + 7) / 8]; -+ char name[256] = "Unknown"; -+ -+ keyboard_fd_num = 0; -+ for (i=0; i<MAX_KEYBOARDS; i++) { -+ keyboard_fds[i] = 0; -+ } - -- for (i=0; i<32; i++) { -+ for (i=0; i<MAX_INPUT_NODE; i++) { - snprintf(filename,sizeof(filename), "/dev/input/event%d", i); -- -+ - fd = open(filename, O_RDWR|O_SYNC); - ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask); -- -- /* We assume that anything that has an alphabetic key in the -- QWERTYUIOP range in it is the main keyboard. */ -- for (j = KEY_Q; j <= KEY_P; j++) { -- if (TestBit(j, key_bitmask)) -- return fd; -+ -+ // Ensure that we do not detect our own tsak faked keyboards -+ ioctl (fd, EVIOCGNAME (sizeof (name)), name); -+ if (str_ends_with(name, "+tsak") == 0) { -+ /* We assume that anything that has an alphabetic key in the -+ QWERTYUIOP range in it is the main keyboard. */ -+ for (j = KEY_Q; j <= KEY_P; j++) { -+ if (TestBit(j, key_bitmask)) { -+ keyboard_fds[keyboard_fd_num] = fd; -+ } -+ } -+ } -+ -+ if (keyboard_fds[keyboard_fd_num] == 0) { -+ close (fd); -+ } -+ else { -+ keyboard_fd_num++; - } -- -- close (fd); - } - return 0; - } -@@ -144,6 +193,12 @@ void tearDownPipe() - } - } - -+void tearDownLockingPipe() -+{ -+ close(mPipe_lockfd_out); -+ unlink(FIFO_LOCKFILE_OUT); -+} -+ - bool setFileLock(int fd, bool close_on_failure) - { - struct flock fl; -@@ -154,8 +209,8 @@ bool setFileLock(int fd, bool close_on_failure) - fl.l_len = 1; - - // Set the exclusive file lock -- if (fcntl(mPipe_fd_out, F_SETLK, &fl) == -1) { -- close(mPipe_fd_out); -+ if (fcntl(fd, F_SETLK, &fl) == -1) { -+ close(fd); - return false; - } - -@@ -171,7 +226,7 @@ bool checkFileLock() - fl.l_whence = SEEK_SET; - fl.l_len = 0; - -- int fd = open(FIFO_FILE_OUT, O_RDWR | O_NONBLOCK); -+ int fd = open(FIFO_LOCKFILE_OUT, O_RDWR | O_NONBLOCK); - fcntl(fd, F_GETLK, &fl); /* Overwrites lock structure with preventors. */ - - if (fd > -1) { -@@ -202,6 +257,71 @@ bool setupPipe() - return setFileLock(mPipe_fd_out, true); - } - -+bool setupLockingPipe() -+{ -+ /* Create the FIFOs if they do not exist */ -+ umask(0); -+ mkdir(FIFO_DIR,0644); -+ -+ mknod(FIFO_LOCKFILE_OUT, S_IFIFO|0600, 0); -+ chmod(FIFO_LOCKFILE_OUT, 0600); -+ -+ mPipe_lockfd_out = open(FIFO_LOCKFILE_OUT, O_RDWR | O_NONBLOCK); -+ if (mPipe_lockfd_out > -1) { -+ // Set the exclusive file lock -+ return setFileLock(mPipe_lockfd_out, true); -+ } -+ -+ return false; -+} -+ -+void broadcast_sak() -+{ -+ // Let anyone listening to our interface know that an SAK keypress was received -+ // I highly doubt there are more than 255 VTs active at once... -+ int i; -+ for (i=0;i<255;i++) { -+ write(mPipe_fd_out, "SAK\n\r", 6); -+ } -+} -+ -+void restart_tsak() -+{ -+ int i; -+ -+ fprintf(stderr, "Forcibly terminating...\n"); -+ -+ // Close down all child processes -+ for (i=0; i<MAX_KEYBOARDS; i++) { -+ if (child_pids[i] != 0) { -+ kill(child_pids[i], SIGKILL); -+ } -+ } -+ -+ // Wait for process termination -+ sleep(1); -+ -+ // Release all exclusive keyboard locks -+ for (int current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { -+ if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 0) < 0) { -+ fprintf(stderr, "Failed to release exclusive input device lock"); -+ } -+ close(keyboard_fds[current_keyboard]); -+ } -+ -+#if 1 -+ // Restart now -+ // Note that the execl function never returns -+ char me[2048]; -+ int chars = readlink("/proc/self/exe", me, sizeof(me)); -+ me[chars] = 0; -+ me[2047] = 0; -+ execl(me, basename(me), (char*)NULL); -+#else -+ _exit(0); -+#endif -+} -+ - class PipeHandler - { - public: -@@ -215,7 +335,7 @@ PipeHandler::PipeHandler() - - PipeHandler::~PipeHandler() - { -- tearDownPipe(); -+ tearDownLockingPipe(); - } - - int main (int argc, char *argv[]) -@@ -223,13 +343,19 @@ int main (int argc, char *argv[]) - struct input_event ev[64]; - struct input_event event; - struct uinput_user_dev devinfo={0}; -- int fd, devout, rd, value, size = sizeof (struct input_event); -+ int devout[MAX_KEYBOARDS], rd, i, value, size = sizeof (struct input_event); - char name[256] = "Unknown"; - bool ctrl_down = false; - bool alt_down = false; - bool hide_event = false; - bool established = false; - bool testrun = false; -+ int current_keyboard; -+ bool can_proceed; -+ -+ for (i=0; i<MAX_KEYBOARDS; i++) { -+ child_pids[i] = 0; -+ } - - if (argc == 2) { - if (strcmp(argv[1], "checkactive") == 0) { -@@ -239,7 +365,11 @@ int main (int argc, char *argv[]) - - // Check for existing file locks - if (!checkFileLock()) { -- fprintf(stderr, "Another instance of this program is already running\n"); -+ fprintf(stderr, "Another instance of this program is already running [1]\n"); -+ return 8; -+ } -+ if (!setupLockingPipe()) { -+ fprintf(stderr, "Another instance of this program is already running [2]\n"); - return 8; - } - -@@ -256,125 +386,227 @@ int main (int argc, char *argv[]) - return 5; - } - -- // Open Device -- fd = find_keyboard(); -- if (fd == -1) { -- printf ("Could not find your keyboard!\n"); -+ // Find keyboards -+ find_keyboards(); -+ if (keyboard_fd_num == 0) { -+ printf ("Could not find any usable keyboard(s)!\n"); -+ // Make sure everyone knows we physically can't detect a SAK -+ // Before we do this we broadcast one so that active dialogs are updated appropriately -+ // Also, we keep watching for a keyboard to be added via a forked child process... -+ broadcast_sak(); - if (established) - sleep(1); -- else -- return 4; -+ else { -+ int i=fork(); -+ if (i<0) return 12; // fork failed -+ if (i>0) { -+ return 4; -+ } -+ sleep(1); -+ restart_tsak(); -+ } - } - else { -- // Print Device Name -- ioctl (fd, EVIOCGNAME (sizeof (name)), name); -- fprintf(stderr, "Reading From : (%s)\n", name); -- -- // Create filtered virtual output device -- devout=open("/dev/misc/uinput",O_WRONLY|O_NONBLOCK); -- if (devout<0) { -- perror("open(\"/dev/misc/uinput\")"); -- devout=open("/dev/uinput",O_WRONLY|O_NONBLOCK); -- } -- if (devout<0) { -- fprintf(stderr,"Unable to open /dev/uinput or /dev/misc/uinput (char device 10:223).\nPossible causes:\n 1) Device node does not exist\n 2) Kernel not compiled with evdev [INPUT_EVDEV] and uinput [INPUT_UINPUT] user level driver support\n 3) Permission denied.\n"); -- perror("open(\"/dev/uinput\")"); -- if (established) -- sleep(1); -- else -- return 3; -- } -- else { -- if(ioctl(fd, EVIOCGRAB, 2) < 0) { -- close(fd); -- fprintf(stderr, "Failed to grab exclusive input device lock"); -+ fprintf(stderr, "Found %d keyboard(s)\n", keyboard_fd_num); -+ -+ can_proceed = true; -+ for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { -+ // Print Device Name -+ ioctl (keyboard_fds[current_keyboard], EVIOCGNAME (sizeof (name)), name); -+ fprintf(stderr, "Reading from keyboard: (%s)\n", name); -+ -+ // Create filtered virtual output device -+ devout[current_keyboard]=open("/dev/misc/uinput",O_WRONLY|O_NONBLOCK); -+ if (devout[current_keyboard]<0) { -+ devout[current_keyboard]=open("/dev/uinput",O_WRONLY|O_NONBLOCK); -+ if (devout[current_keyboard]<0) { -+ perror("open(\"/dev/misc/uinput\")"); -+ } -+ } -+ if (devout[current_keyboard]<0) { -+ can_proceed = false; -+ fprintf(stderr, "Unable to open /dev/uinput or /dev/misc/uinput (char device 10:223).\nPossible causes:\n 1) Device node does not exist\n 2) Kernel not compiled with evdev [INPUT_EVDEV] and uinput [INPUT_UINPUT] user level driver support\n 3) Permission denied.\n"); -+ perror("open(\"/dev/uinput\")"); - if (established) - sleep(1); - else -- return 1; -+ return 3; - } -- else { -- ioctl(fd, EVIOCGNAME(UINPUT_MAX_NAME_SIZE), devinfo.name); -- strncat(devinfo.name, "+tsak", UINPUT_MAX_NAME_SIZE-1); -- fprintf(stderr, "%s\n", devinfo.name); -- ioctl(fd, EVIOCGID, &devinfo.id); -- -- copy_features(fd, devout); -- write(devout,&devinfo,sizeof(devinfo)); -- if (ioctl(devout,UI_DEV_CREATE)<0) { -- fprintf(stderr,"Unable to create input device with UI_DEV_CREATE\n"); -+ } -+ -+ if (can_proceed == true) { -+ for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { -+ if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 2) < 0) { -+ close(keyboard_fds[current_keyboard]); -+ fprintf(stderr, "Failed to grab exclusive input device lock"); - if (established) - sleep(1); - else -- return 2; -+ return 1; - } - else { -- fprintf(stderr,"Device created.\n"); -- -- if (established == false) { -- tearDownPipe(); -- int i=fork(); -- if (i<0) return 9; // fork failed -- if (i>0) { -- // close parent process -- close(mPipe_fd_out); -- return 0; -- } -- setupPipe(); -+ ioctl(keyboard_fds[current_keyboard], EVIOCGNAME(UINPUT_MAX_NAME_SIZE), devinfo.name); -+ strncat(devinfo.name, "+tsak", UINPUT_MAX_NAME_SIZE-1); -+ fprintf(stderr, "%s\n", devinfo.name); -+ ioctl(keyboard_fds[current_keyboard], EVIOCGID, &devinfo.id); -+ -+ copy_features(keyboard_fds[current_keyboard], devout[current_keyboard]); -+ write(devout[current_keyboard],&devinfo,sizeof(devinfo)); -+ if (ioctl(devout[current_keyboard],UI_DEV_CREATE)<0) { -+ fprintf(stderr, "Unable to create input device with UI_DEV_CREATE\n"); -+ if (established) -+ sleep(1); -+ else -+ return 2; - } -- -- established = true; -- -- if (testrun == true) { -- return 0; -- } -- -- while (1) { -- if ((rd = read (fd, ev, size * 2)) < size) { -- fprintf(stderr,"Read failed.\n"); -- break; -- } -- -- value = ev[0].value; -- -- if (value != ' ' && ev[1].value == 0 && ev[1].type == 1){ // Read the key release event -- if (keycode[(ev[1].code)]) { -- if (strcmp(keycode[(ev[1].code)], "<control>") == 0) ctrl_down = false; -- if (strcmp(keycode[(ev[1].code)], "<alt>") == 0) alt_down = false; -+ else { -+ fprintf(stderr, "Device created.\n"); -+ -+ if (established == false) { -+ int i=fork(); -+ if (i<0) return 9; // fork failed -+ if (i>0) { -+ child_pids[current_keyboard] = i; -+ continue; - } -+ setupLockingPipe(); - } -- if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Read the key press event -- if (keycode[(ev[1].code)]) { -- if (strcmp(keycode[(ev[1].code)], "<control>") == 0) ctrl_down = true; -- if (strcmp(keycode[(ev[1].code)], "<alt>") == 0) alt_down = true; -- } -+ -+ established = true; -+ -+ if (testrun == true) { -+ return 0; - } - -- hide_event = false; -- if (keycode[(ev[1].code)]) { -- if (alt_down && ctrl_down && (strcmp(keycode[(ev[1].code)], "<del>") == 0)) { -- hide_event = true; -+ while (1) { -+ if ((rd = read (keyboard_fds[current_keyboard], ev, size * 2)) < size) { -+ fprintf(stderr, "Read failed.\n"); -+ break; -+ } -+ -+ value = ev[0].value; -+ -+ if (value != ' ' && ev[1].value == 0 && ev[1].type == 1){ // Read the key release event -+ if (keycode[(ev[1].code)]) { -+ if (strcmp(keycode[(ev[1].code)], "<control>") == 0) ctrl_down = false; -+ if (strcmp(keycode[(ev[1].code)], "<alt>") == 0) alt_down = false; -+ } -+ } -+ if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Read the key press event -+ if (keycode[(ev[1].code)]) { -+ if (strcmp(keycode[(ev[1].code)], "<control>") == 0) ctrl_down = true; -+ if (strcmp(keycode[(ev[1].code)], "<alt>") == 0) alt_down = true; -+ } -+ } -+ -+ hide_event = false; -+ if (keycode[(ev[1].code)]) { -+ if (alt_down && ctrl_down && (strcmp(keycode[(ev[1].code)], "<del>") == 0)) { -+ hide_event = true; -+ } -+ } -+ -+ if (hide_event == false) { -+ // Pass the event on... -+ event = ev[0]; -+ write(devout[current_keyboard], &event, sizeof event); -+ event = ev[1]; -+ write(devout[current_keyboard], &event, sizeof event); -+ } -+ if (hide_event == true) { -+ // Let anyone listening to our interface know that an SAK keypress was received -+ broadcast_sak(); - } - } -+ } -+ } -+ } -+ -+ // fork udev monitor process -+ int i=fork(); -+ if (i<0) return 10; // fork failed -+ if (i>0) { -+ // Terminate parent -+ return 0; -+ } -+ -+ // Prevent multiple process instances from starting -+ setupLockingPipe(); -+ -+ // Wait a little bit so that udev hotplug can stabilize before we start monitoring -+ sleep(1); -+ -+ fprintf(stderr, "Hotplug monitoring process started\n"); -+ -+ // Monitor for hotplugged keyboards -+ int j; -+ int hotplug_fd; -+ bool is_new_keyboard; -+ struct udev *udev; -+ struct udev_device *dev; -+ struct udev_monitor *mon; -+ -+ // Create the udev object -+ udev = udev_new(); -+ if (!udev) { -+ fprintf(stderr, "Cannot connect to udev interface\n"); -+ return 11; -+ } -+ -+ // Set up a udev monitor to monitor input devices -+ mon = udev_monitor_new_from_netlink(udev, "udev"); -+ udev_monitor_filter_add_match_subsystem_devtype(mon, "input", NULL); -+ udev_monitor_enable_receiving(mon); -+ -+ while (1) { -+ // Watch for input from the monitoring process -+ dev = udev_monitor_receive_device(mon); -+ if (dev) { -+ // If a keyboard was removed we need to restart... -+ if (strcmp(udev_device_get_action(dev), "remove") == 0) { -+ udev_device_unref(dev); -+ udev_unref(udev); -+ restart_tsak(); -+ } -+ -+ is_new_keyboard = false; -+ snprintf(filename,sizeof(filename), "%s", udev_device_get_devnode(dev)); -+ udev_device_unref(dev); -+ -+ // Print name of keyboard -+ hotplug_fd = open(filename, O_RDWR|O_SYNC); -+ ioctl(hotplug_fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask); - -- if (hide_event == false) { -- // Pass the event on... -- event = ev[0]; -- write(devout, &event, sizeof event); -- event = ev[1]; -- write(devout, &event, sizeof event); -- } -- if (hide_event == true) { -- // Let anyone listening to our interface know that an SAK keypress was received -- // I highly doubt there are more than 255 VTs active at once... -- int i; -- for (i=0;i<255;i++) { -- write(mPipe_fd_out, "SAK\n\r", 6); -- } -+ /* We assume that anything that has an alphabetic key in the -+ QWERTYUIOP range in it is the main keyboard. */ -+ for (j = KEY_Q; j <= KEY_P; j++) { -+ if (TestBit(j, key_bitmask)) { -+ is_new_keyboard = true; - } - } -+ ioctl (hotplug_fd, EVIOCGNAME (sizeof (name)), name); -+ close(hotplug_fd); -+ -+ // Ensure that we do not detect our own tsak faked keyboards -+ if (str_ends_with(name, "+tsak") == 1) { -+ is_new_keyboard = false; -+ } -+ -+ // If a keyboard was added we need to restart... -+ if (is_new_keyboard == true) { -+ fprintf(stderr, "Hotplugged new keyboard: (%s)\n", name); -+ udev_unref(udev); -+ restart_tsak(); -+ } -+ } -+ else { -+ fprintf(stderr, "No Device from receive_device(). An error occured.\n"); - } - } -+ -+ udev_unref(udev); -+ -+ fprintf(stderr, "Hotplug monitoring process terminated\n"); - } - } - } -diff --git a/twin/kompmgr/kompmgr.c b/twin/kompmgr/kompmgr.c -index 5daf8c2..8216676 100644 ---- a/kwin/kompmgr/kompmgr.c -+++ b/kwin/kompmgr/kompmgr.c -@@ -60,6 +60,7 @@ check baghira.sf.net for more infos - #include <signal.h> - #include <time.h> - #include <unistd.h> -+#include <libgen.h> - #include <X11/Xlib.h> - #include <X11/Xutil.h> - #include <X11/Xatom.h> -@@ -397,7 +398,7 @@ void delete_pid_file() - int chars = readlink("/proc/self/exe", me, sizeof(me)); - me[chars] = 0; - me[2047] = 0; -- execl(me, NULL); -+ execl(me, basename(me), (char*)NULL); - } - #endif - } |