ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
main.c File Reference
#include "device.h"
#include "devnode.h"
#include "input.h"
#include "led.h"
#include "notify.h"
+ Include dependency graph for main.c:

Go to the source code of this file.

Functions

static void quitWithLock (char mut)
 quitWithLock More...
 
int restart ()
 
void timespec_add (struct timespec *timespec, long nanoseconds)
 
static void quit ()
 quit Stop working the daemon. function is called if the daemon received a sigterm In this case, locking the device-mutex is ok. More...
 
void sighandler2 (int type)
 
void sighandler (int type)
 
void localecase (char *dst, size_t length, const char *src)
 
int main (int argc, char **argv)
 

Variables

static int main_ac
 
static char ** main_av
 
volatile int reset_stop
 brief . More...
 
int features_mask
 brief . More...
 
int hwload_mode
 hwload_mode = 1 means read hardware once. should be enough More...
 

Function Documentation

void localecase ( char *  dst,
size_t  length,
const char *  src 
)

Definition at line 71 of file main.c.

71  {
72  char* ldst = dst + length;
73  char s;
74  while((s = *src++)){
75  if(s == '_')
76  s = '-';
77  else
78  s = tolower(s);
79  *dst++ = s;
80  if(dst == ldst){
81  dst--;
82  break;
83  }
84  }
85  *dst = 0;
86 }
int main ( int  argc,
char **  argv 
)

Definition at line 88 of file main.c.

References ckb_fatal_nofile, ckb_info(), ckb_info_nofile, ckb_warn_nofile, devpath, FEAT_BIND, FEAT_MOUSEACCEL, FEAT_NOTIFY, features_mask, gid, hwload_mode, keyboard, main_ac, main_av, mkdevpath(), quit(), restart(), sighandler(), and usbmain().

Referenced by restart().

88  {
89  // Set output pipes to buffer on newlines, if they weren't set that way already
90  setlinebuf(stdout);
91  setlinebuf(stderr);
92  main_ac = argc;
93  main_av = argv;
94 
95  printf(" ckb: Corsair RGB driver %s\n", CKB_VERSION_STR);
96  // If --help occurs anywhere in the command-line, don't launch the program but instead print usage
97  for(int i = 1; i < argc; i++){
98  if(!strcmp(argv[i], "--help")){
99  printf(
100 #ifdef OS_MAC
101  "Usage: ckb-daemon [--gid=<gid>] [--hwload=<always|try|never>] [--nonotify] [--nobind] [--nomouseaccel] [--nonroot]\n"
102 #else
103  "Usage: ckb-daemon [--gid=<gid>] [--hwload=<always|try|never>] [--nonotify] [--nobind] [--nonroot]\n"
104 #endif
105  "\n"
106  "See https://github.com/ccMSC/ckb/blob/master/DAEMON.md for full instructions.\n"
107  "\n"
108  "Command-line parameters:\n"
109  " --gid=<gid>\n"
110  " Restrict access to %s* nodes to users in group <gid>.\n"
111  " (Ordinarily they are accessible to anyone)\n"
112  " --hwload=<always|try|never>\n"
113  " --hwload=always will force loading of stored hardware profiles on compatible devices. May result in long start up times.\n"
114  " --hwload=try will try to load the profiles, but give up if not immediately successful (default).\n"
115  " --hwload=never will ignore hardware profiles completely.\n"
116  " --nonotify\n"
117  " Disables key monitoring/notifications.\n"
118  " Note that this makes reactive lighting impossible.\n"
119  " --nobind\n"
120  " Disables all key rebinding, macros, and notifications. Implies --nonotify.\n"
121 #ifdef OS_MAC
122  " --nomouseaccel\n"
123  " Disables mouse acceleration, even if the system preferences enable it.\n"
124 #endif
125  " --nonroot\n"
126  " Allows running ckb-daemon as a non root user.\n"
127  " This will almost certainly not work. Use only if you know what you're doing.\n"
128  "\n", devpath);
129  exit(0);
130  }
131  }
132 
133  // Check PID, quit if already running
134  char pidpath[strlen(devpath) + 6];
135  snprintf(pidpath, sizeof(pidpath), "%s0/pid", devpath);
136  FILE* pidfile = fopen(pidpath, "r");
137  if(pidfile){
138  pid_t pid;
139  fscanf(pidfile, "%d", &pid);
140  fclose(pidfile);
141  if(pid > 0){
142  // kill -s 0 checks if the PID is active but doesn't send a signal
143  if(!kill(pid, 0)){
144  ckb_fatal_nofile("ckb-daemon is already running (PID %d). Try `killall ckb-daemon`.\n", pid);
145  ckb_fatal_nofile("(If you're certain the process is dead, delete %s and try again)\n", pidpath);
146  return 0;
147  }
148  }
149  }
150 
151  // Read parameters
152  int forceroot = 1;
153  for(int i = 1; i < argc; i++){
154  char* argument = argv[i];
155  unsigned newgid;
156  char hwload[7];
157  if(sscanf(argument, "--gid=%u", &newgid) == 1){
158  // Set dev node GID
159  gid = newgid;
160  ckb_info_nofile("Setting /dev node gid: %u\n", newgid);
161  } else if(!strcmp(argument, "--nobind")){
162  // Disable key notifications and rebinding
164  ckb_info_nofile("Key binding and key notifications are disabled\n");
165  } else if(!strcmp(argument, "--nonotify")){
166  // Disable key notifications
168  ckb_info_nofile("Key notifications are disabled\n");
169  } else if(sscanf(argument, "--hwload=%6s", hwload) == 1){
170  if(!strcmp(hwload, "always") || !strcmp(hwload, "yes") || !strcmp(hwload, "y") || !strcmp(hwload, "a")){
171  hwload_mode = 2;
172  ckb_info_nofile("Setting hardware load: always\n");
173  } else if(!strcmp(hwload, "tryonce") || !strcmp(hwload, "try") || !strcmp(hwload, "once") || !strcmp(hwload, "t") || !strcmp(hwload, "o")){
174  hwload_mode = 1;
175  ckb_info_nofile("Setting hardware load: tryonce\n");
176  } else if(!strcmp(hwload, "never") || !strcmp(hwload, "none") || !strcmp(hwload, "no") || !strcmp(hwload, "n")){
177  hwload_mode = 0;
178  ckb_info_nofile("Setting hardware load: never\n");
179  }
180  } else if(!strcmp(argument, "--nonroot")){
181  // Allow running as a non-root user
182  forceroot = 0;
183  }
184 #ifdef OS_MAC
185  else if(!strcmp(argument, "--nomouseaccel")){
186  // On OSX, provide an option to disable mouse acceleration
188  ckb_info_nofile("Mouse acceleration disabled\n");
189  }
190 #endif
191  }
192 
193  // Check UID
194  if(getuid() != 0){
195  if(forceroot){
196  ckb_fatal_nofile("ckb-daemon must be run as root. Try `sudo %s`\n", argv[0]);
197  exit(0);
198  } else
199  ckb_warn_nofile("Warning: not running as root, allowing anyway per command-line parameter...\n");
200  }
201 
202  // Make root keyboard
203  umask(0);
204  memset(keyboard, 0, sizeof(keyboard));
205  if(!mkdevpath(keyboard))
206  ckb_info("Root controller ready at %s0\n", devpath);
207 
208  // Set signals
209  sigset_t signals;
210  sigfillset(&signals);
211  sigdelset(&signals, SIGTERM);
212  sigdelset(&signals, SIGINT);
213  sigdelset(&signals, SIGQUIT);
214  sigdelset(&signals, SIGUSR1);
215  // Set up signal handlers for quitting the service.
216  sigprocmask(SIG_SETMASK, &signals, 0);
217  signal(SIGTERM, sighandler);
218  signal(SIGINT, sighandler);
219  signal(SIGQUIT, sighandler);
220  signal(SIGUSR1, (void (*)())restart);
221 
222  // Start the USB system
223  int result = usbmain();
224  quit();
225  return result;
226 }
int features_mask
brief .
Definition: usb.c:35
static char ** main_av
Definition: main.c:8
int hwload_mode
hwload_mode = 1 means read hardware once. should be enough
Definition: device.c:7
#define FEAT_MOUSEACCEL
Definition: structures.h:148
int restart()
Definition: main.c:228
int usbmain()
Start the USB main loop. Returns program exit code when finished.
Definition: usb_linux.c:793
int mkdevpath(usbdevice *kb)
Create a dev path for the keyboard at index. Returns 0 on success.
Definition: devnode.c:268
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
Definition: device.c:10
static void quit()
quit Stop working the daemon. function is called if the daemon received a sigterm In this case...
Definition: main.c:30
#define FEAT_BIND
Definition: structures.h:140
QString devpath
Definition: kbmanager.cpp:4
long gid
Group ID for the control nodes. -1 to give read/write access to everybody.
Definition: devnode.c:16
#define ckb_warn_nofile(fmt, args...)
Definition: includes.h:50
#define ckb_fatal_nofile(fmt, args...)
Definition: includes.h:44
void ckb_info()
Definition: main.c:5
void sighandler(int type)
Definition: main.c:62
#define FEAT_NOTIFY
Definition: structures.h:141
static int main_ac
Definition: main.c:7
#define ckb_info_nofile(fmt, args...)
Definition: includes.h:53

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void quit ( )
static

Definition at line 30 of file main.c.

References quitWithLock().

Referenced by KbFirmware::_fileForBoard(), KbFirmware::_latestForBoard(), FwUpgradeDialog::fwUpdateFinished(), main(), and sighandler().

30  {
31  quitWithLock(1);
32 }
static void quitWithLock(char mut)
quitWithLock
Definition: main.c:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void quitWithLock ( char  mut)
static
Parameters
muttry to close files maybe without locking the mutex if mut == true then lock

Definition at line 40 of file main.c.

References ckb_info(), closeusb(), DEV_MAX, devmutex, IS_CONNECTED, keyboard, reset_stop, revertusb(), rmdevpath(), and usbkill().

Referenced by quit(), and restart().

40  {
41  // Abort any USB resets in progress
42  reset_stop = 1;
43  for(int i = 1; i < DEV_MAX; i++){
44  // Before closing, set all keyboards back to HID input mode so that the stock driver can still talk to them
45  if (mut) pthread_mutex_lock(devmutex + i);
46  if(IS_CONNECTED(keyboard + i)){
47  revertusb(keyboard + i);
48  closeusb(keyboard + i);
49  }
50  pthread_mutex_unlock(devmutex + i);
51  }
52  ckb_info("Closing root controller\n");
54  usbkill();
55 }
#define IS_CONNECTED(kb)
Definition: device.h:12
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
Definition: device.c:10
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure.
Definition: device.c:12
void ckb_info()
Definition: main.c:5
int closeusb(usbdevice *kb)
Definition: usb.c:687
volatile int reset_stop
brief .
Definition: usb.c:25
#define DEV_MAX
Definition: device.h:8
void usbkill()
Stop the USB system.
Definition: usb_linux.c:853
int rmdevpath(usbdevice *kb)
Remove the dev path for the keyboard at index. Returns 0 on success.
Definition: devnode.c:275
int revertusb(usbdevice *kb)
Definition: usb.c:417

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int restart ( )

Definition at line 228 of file main.c.

References ckb_err, main(), main_ac, main_av, and quitWithLock().

Referenced by cmd_restart(), and main().

228  {
229  ckb_err("restart called, running quit without mutex-lock.\n");
230  quitWithLock(0);
231  return main(main_ac, main_av);
232 }
static char ** main_av
Definition: main.c:8
#define ckb_err(fmt, args...)
Definition: includes.h:49
int main(int argc, char **argv)
Definition: main.c:88
static void quitWithLock(char mut)
quitWithLock
Definition: main.c:40
static int main_ac
Definition: main.c:7

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void sighandler ( int  type)

Definition at line 62 of file main.c.

References quit(), and sighandler2().

Referenced by main().

62  {
63  signal(SIGTERM, sighandler2);
64  signal(SIGINT, sighandler2);
65  signal(SIGQUIT, sighandler2);
66  printf("\n[I] Caught signal %d\n", type);
67  quit();
68  exit(0);
69 }
static void quit()
quit Stop working the daemon. function is called if the daemon received a sigterm In this case...
Definition: main.c:30
void sighandler2(int type)
Definition: main.c:57

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void sighandler2 ( int  type)

Definition at line 57 of file main.c.

Referenced by sighandler().

57  {
58  // Don't use ckb_warn, we want an extra \n at the beginning
59  printf("\n[W] Ignoring signal %d (already shutting down)\n", type);
60 }

+ Here is the caller graph for this function:

void timespec_add ( struct timespec *  timespec,
long  nanoseconds 
)

Definition at line 19 of file main.c.

19  {
20  nanoseconds += timespec->tv_nsec;
21  timespec->tv_sec += nanoseconds / 1000000000;
22  timespec->tv_nsec = nanoseconds % 1000000000;
23 }

Variable Documentation

int features_mask

features_mask Mask of features to exclude from all devices

That bit mask ist set to enable all (-1). When interpreting the input parameters, some of these bits can be cleared.
At the moment binding, notifying and mouse-acceleration can be disabled via command line.
Have a look at main() in main.c for details.

Definition at line 35 of file usb.c.

Referenced by _setupusb(), and main().

int hwload_mode

Definition at line 7 of file device.c.

Referenced by main().

int main_ac
static

Definition at line 7 of file main.c.

Referenced by main(), and restart().

char** main_av
static

Definition at line 8 of file main.c.

Referenced by main(), and restart().

volatile int reset_stop

reset_stop is boolean: Reset stopper for when the program shuts down.

Is set only by quit() to true (1) to inform several usb_* functions to end their loops and tries.

Definition at line 25 of file usb.c.

Referenced by _usbrecv(), _usbsend(), quitWithLock(), and usb_tryreset().