Initial commit.
This commit is contained in:
commit
d077fbf833
4 files changed
+245
No files matched your search
@@ -0,0 +1,89 @@
|
|||||||
|
UNAME_M := $(shell uname -m)
|
||||||
|
|
||||||
|
ifeq ($(UNAME_M),x86_64)
|
||||||
|
ARCH := ARCHITECTURE_X64
|
||||||
|
else ifneq ($(filter $(UNAME_M),i686,i386),)
|
||||||
|
ARCH := ARCHITECTURE_X86
|
||||||
|
else ifneq ($(filter $(UNAME_M),aarch64 arm64),)
|
||||||
|
ARCH := ARCHITECTURE_ARM64
|
||||||
|
else ifneq ($(filter $(UNAME_M),armv7l armv6l),)
|
||||||
|
ARCH := ARCHITECTURE_ARM32
|
||||||
|
endif
|
||||||
|
|
||||||
|
UNAME_E := $(shell [ $$(printf '\01\00' | od -An -tu2) -eq 1 ] && \
|
||||||
|
echo "little" || echo "big")
|
||||||
|
|
||||||
|
ifeq ($(UNAME_E),little)
|
||||||
|
ENDIANESS := LITTLE_ENDIAN
|
||||||
|
else ifeq ($(UNAME_E),little)
|
||||||
|
ENDIANESS := BIG_ENDIAN
|
||||||
|
endif
|
||||||
|
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
OS := OS_MACOS
|
||||||
|
else ifeq ($(UNAME_S),Linux)
|
||||||
|
OS := OS_LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
|
||||||
|
ifeq ($(CC),clang)
|
||||||
|
COMP := COMPILER_CLANG
|
||||||
|
else ifeq ($(CC),gcc)
|
||||||
|
COMP := COMPILER_GCC
|
||||||
|
endif
|
||||||
|
|
||||||
|
# -ansi -pedantic -pedantic-errors
|
||||||
|
CFLAGS = -Wno-long-long -Wall -Wextra \
|
||||||
|
-Wincompatible-pointer-types \
|
||||||
|
-Wint-conversion -Wformat \
|
||||||
|
-Wno-strict-prototypes -Wno-missing-field-initializers \
|
||||||
|
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
|
||||||
|
-Wno-unused-but-set-variable \
|
||||||
|
-fno-show-column
|
||||||
|
|
||||||
|
ifeq ($(COMP),COMPILER_CLANG)
|
||||||
|
CFLAGS += -fno-caret-diagnostics
|
||||||
|
else ifeq ($(COMP),COMPILER_GCC)
|
||||||
|
CFLAGS += -fno-diagnostics-show-caret
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(OS),OS_MACOS)
|
||||||
|
FLAGS = -glldb
|
||||||
|
INCLUDE =
|
||||||
|
LIBS =
|
||||||
|
FRAMEWORKS =
|
||||||
|
else ifeq ($(OS),OS_LINUX)
|
||||||
|
FLAGS = -O3 #-ggdb -DDEBUG=1 -DINTERNAL=1
|
||||||
|
INCLUDE =
|
||||||
|
LIBS =
|
||||||
|
FRAMEWORKS =
|
||||||
|
endif
|
||||||
|
|
||||||
|
EXE = hid_apple_fn_lock
|
||||||
|
|
||||||
|
default: $(EXE)
|
||||||
|
|
||||||
|
$(EXE): $(EXE).c
|
||||||
|
$(CC) $(CFLAGS) $(FLAGS) \
|
||||||
|
-D$(ARCH)=1 -D$(ENDIANESS)=1 -D$(OS)=1 -D$(COMP)=1 \
|
||||||
|
-D_DEFAULT_SOURCE -DHAVE_SHADOW_H \
|
||||||
|
$(INCLUDE) $^ $(LIBS) \
|
||||||
|
$(FRAMEWORKS) -o $@ $(ifneq $(filter $(OS), OS_MACOS OS_LINUX), \
|
||||||
|
/link /FORCE:MULTIPLE)
|
||||||
|
|
||||||
|
watch:
|
||||||
|
@ while true; do \
|
||||||
|
inotifywait -q -q -e 'modify' . && clear && make -B; \
|
||||||
|
done
|
||||||
|
|
||||||
|
perf:
|
||||||
|
perf record --call-graph dwarf ./$(EXE)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@ clear; ./$(EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@ rm -rf $(EXE) $(EXE).dSYM
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
#include <unistd.h> /* access */
|
||||||
|
#include <stdlib.h> /* exit */
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h> /* strcmp */
|
||||||
|
|
||||||
|
/* Kernel module entry for the Apple Human Interface Device driver. */
|
||||||
|
#define APPLE_HID_PATH "/sys/module/hid_apple"
|
||||||
|
|
||||||
|
char file_exists(const char *filename)
|
||||||
|
{
|
||||||
|
return access(filename, F_OK) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int init_apple_hid_module()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if(!file_exists(APPLE_HID_PATH)) {
|
||||||
|
syslog(LOG_WARNING, "Apple hid module is unloaded.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(APPLE_HID_PATH"/parameters/fnmode", O_RDWR);
|
||||||
|
if(fd == -1) {
|
||||||
|
syslog(LOG_WARNING, "Failed to open %s.",
|
||||||
|
APPLE_HID_PATH"/parameters/fnmode");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_fn_lock()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char state;
|
||||||
|
|
||||||
|
fd = init_apple_hid_module();
|
||||||
|
if(fd != -1) {
|
||||||
|
if(read(fd, &state, 1) != 1)
|
||||||
|
state = '0';
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state == '2';
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fn_lock_on()
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = init_apple_hid_module();
|
||||||
|
if(fd != -1) {
|
||||||
|
if(write(fd, "2", 1) != 1)
|
||||||
|
syslog(LOG_WARNING, "Failed to write to Apple HID driver.");
|
||||||
|
else
|
||||||
|
syslog(LOG_INFO, "Fn lock is on.");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fn_lock_off()
|
||||||
|
{
|
||||||
|
int fd = init_apple_hid_module();
|
||||||
|
if(fd != -1) {
|
||||||
|
if(write(fd, "1", 1) != 1)
|
||||||
|
syslog(LOG_WARNING, "Failed to write Apple HID driver.");
|
||||||
|
else
|
||||||
|
syslog(LOG_INFO, "Fn lock is off.");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void daemonize()
|
||||||
|
{
|
||||||
|
close(0);
|
||||||
|
close(1);
|
||||||
|
close(2);
|
||||||
|
open("/dev/null", O_RDONLY); /* stdin */
|
||||||
|
open("/dev/null", O_WRONLY); /* stdout */
|
||||||
|
open("/dev/null", O_WRONLY); /* stderr */
|
||||||
|
chdir("/");
|
||||||
|
int pid = fork();
|
||||||
|
if(pid > 0)
|
||||||
|
exit(0);
|
||||||
|
setsid();
|
||||||
|
pid = fork();
|
||||||
|
if(pid > 0)
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
static volatile sig_atomic_t n = 0;
|
||||||
|
|
||||||
|
void usr1hdl(int sig)
|
||||||
|
{
|
||||||
|
int save_errno = errno;
|
||||||
|
signal(SIGUSR1, usr1hdl);
|
||||||
|
n = 0;
|
||||||
|
errno = save_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
void termhdl(int sig)
|
||||||
|
{
|
||||||
|
int save_errno = errno;
|
||||||
|
signal(SIGTERM, termhdl);
|
||||||
|
n = 1;
|
||||||
|
errno = save_errno;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
/*daemonize();*/
|
||||||
|
|
||||||
|
signal(SIGUSR1, usr1hdl);
|
||||||
|
signal(SIGTERM, termhdl);
|
||||||
|
|
||||||
|
openlog("hid_apple_fn_lock", 0, LOG_USER);
|
||||||
|
syslog(LOG_INFO, "Daemon started, pid == %d", getpid());
|
||||||
|
|
||||||
|
uid_t euid = geteuid();
|
||||||
|
if(euid != 0) {
|
||||||
|
syslog(LOG_WARNING, "Must have root priviliges. Quitting...");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
pause();
|
||||||
|
if(n == 0) {
|
||||||
|
if(get_fn_lock())
|
||||||
|
set_fn_lock_off();
|
||||||
|
else
|
||||||
|
set_fn_lock_on();
|
||||||
|
} else if(n == 1) {
|
||||||
|
syslog(LOG_INFO, "Shutting down...");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closelog();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exec chpst -u igor svlogd -tt /opt/hid_apple_fn_lock/logs
|
||||||
Executable
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
exec 2>&1
|
||||||
|
exec chpst -u igor /usr/local/bin/hid_apple_fn_lock
|
||||||
Reference in new issue
Block a user