Initial commit.
This commit is contained in:
commit
d077fbf833
4 files changed
+245
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user