|
@@ -1,5 +1,6 @@
|
1
|
1
|
#include "light.h"
|
2
|
2
|
|
|
3
|
+#include <libgen.h>
|
3
|
4
|
#include <stdlib.h>
|
4
|
5
|
#include <stdio.h>
|
5
|
6
|
#include <string.h>
|
|
@@ -281,11 +282,34 @@ static bool light_parse_args(int argc, char **argv)
|
281
|
282
|
return true;
|
282
|
283
|
}
|
283
|
284
|
|
|
285
|
+static int mkpath(char *dir, mode_t mode)
|
|
286
|
+{
|
|
287
|
+ struct stat sb;
|
|
288
|
+
|
|
289
|
+ if (!dir) {
|
|
290
|
+ errno = EINVAL;
|
|
291
|
+ return -1;
|
|
292
|
+ }
|
|
293
|
+
|
|
294
|
+ if (!stat(dir, &sb))
|
|
295
|
+ return 0;
|
|
296
|
+
|
|
297
|
+ mkpath(dirname(strdupa(dir)), mode);
|
|
298
|
+
|
|
299
|
+ return mkdir(dir, mode);
|
|
300
|
+}
|
|
301
|
+
|
284
|
302
|
bool light_initialize(int argc, char **argv)
|
285
|
303
|
{
|
286
|
304
|
light_cmd_t mode;
|
287
|
305
|
int rc;
|
288
|
306
|
|
|
307
|
+ /* Classic SUID root mode or new user based cache files */
|
|
308
|
+ if (geteuid() == 0)
|
|
309
|
+ snprintf(ctx.prefix, sizeof(ctx.prefix), "%s", "/etc/light");
|
|
310
|
+ else
|
|
311
|
+ snprintf(ctx.prefix, sizeof(ctx.prefix), "%s/.cache/light", getenv("HOME"));
|
|
312
|
+
|
289
|
313
|
light_defaults();
|
290
|
314
|
if (!light_parse_args(argc, argv)) {
|
291
|
315
|
LIGHT_ERR("could not parse arguments");
|
|
@@ -297,22 +321,23 @@ bool light_initialize(int argc, char **argv)
|
297
|
321
|
if (mode == LIGHT_PRINT_HELP || mode == LIGHT_PRINT_VERSION || mode == LIGHT_LIST_CTRL)
|
298
|
322
|
return true;
|
299
|
323
|
|
|
324
|
+ /* Make sure we have a valid cache directory for all files */
|
300
|
325
|
if (mode == LIGHT_SAVE || (mode == LIGHT_SET && ctx.field == LIGHT_MIN_CAP)) {
|
301
|
|
- /* Make sure we have a valid /etc/light directory, as well as mincap and save */
|
302
|
|
- char const *const dirs[5] =
|
303
|
|
- { "/etc/light", "/etc/light/mincap", "/etc/light/save", "/etc/light/mincap/kbd",
|
304
|
|
- "/etc/light/save/kbd"
|
|
326
|
+ const char *dirs[5] = {
|
|
327
|
+ "/mincap/kbd", "/save/kbd", NULL
|
305
|
328
|
};
|
306
|
|
- char const *const *dir = dirs;
|
|
329
|
+ char path[strlen(ctx.prefix) + 20];
|
|
330
|
+ int i;
|
|
331
|
+
|
|
332
|
+ for (i = 0; dirs[i]; i++) {
|
|
333
|
+ snprintf(path, sizeof(path), "%s%s", ctx.prefix, dirs[i]);
|
307
|
334
|
|
308
|
|
- while (dir < dirs + 5) {
|
309
|
|
- rc = mkdir(*dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
|
335
|
+ rc = mkpath(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
310
|
336
|
if (rc && errno != EEXIST) {
|
311
|
337
|
LIGHT_ERR("'%s' does not exist and could not be created,"
|
312
|
|
- " make sure this application is run as root.", *dir);
|
|
338
|
+ " make sure this application is run as root.", path);
|
313
|
339
|
return false;
|
314
|
340
|
}
|
315
|
|
- ++dir;
|
316
|
341
|
}
|
317
|
342
|
}
|
318
|
343
|
|
|
@@ -584,11 +609,11 @@ bool light_gen_path(char const *controller, light_target_t target, light_field_t
|
584
|
609
|
break;
|
585
|
610
|
|
586
|
611
|
case LIGHT_MIN_CAP:
|
587
|
|
- val = snprintf(path, PATH_MAX, "/etc/light/mincap/%s", controller);
|
|
612
|
+ val = snprintf(path, PATH_MAX, "%s/mincap/%s", ctx.prefix, controller);
|
588
|
613
|
break;
|
589
|
614
|
|
590
|
615
|
case LIGHT_SAVERESTORE:
|
591
|
|
- val = snprintf(path, PATH_MAX, "/etc/light/save/%s", controller);
|
|
616
|
+ val = snprintf(path, PATH_MAX, "%s/save/%s", ctx.prefix, controller);
|
592
|
617
|
break;
|
593
|
618
|
}
|
594
|
619
|
} else {
|
|
@@ -602,11 +627,11 @@ bool light_gen_path(char const *controller, light_target_t target, light_field_t
|
602
|
627
|
break;
|
603
|
628
|
|
604
|
629
|
case LIGHT_MIN_CAP:
|
605
|
|
- val = snprintf(path, PATH_MAX, "/etc/light/mincap/kbd/%s", controller);
|
|
630
|
+ val = snprintf(path, PATH_MAX, "%s/mincap/kbd/%s", ctx.prefix, controller);
|
606
|
631
|
break;
|
607
|
632
|
|
608
|
633
|
case LIGHT_SAVERESTORE:
|
609
|
|
- val = snprintf(path, PATH_MAX, "/etc/light/save/kbd/%s", controller);
|
|
634
|
+ val = snprintf(path, PATH_MAX, "%s/save/kbd/%s", ctx.prefix, controller);
|
610
|
635
|
break;
|
611
|
636
|
}
|
612
|
637
|
}
|
|
@@ -718,8 +743,8 @@ bool light_ctrl_exist(char const *controller)
|
718
|
743
|
if (!light_ctrl_get_brightness_maxPath(controller, &path))
|
719
|
744
|
return false;
|
720
|
745
|
if (!light_file_is_readable(path)) {
|
721
|
|
- LIGHT_WARN
|
722
|
|
- ("could not open controller max brightness file for reading, so controller is not accessible");
|
|
746
|
+ LIGHT_WARN("could not open controller max brightness "
|
|
747
|
+ "file for reading, so controller is not accessible");
|
723
|
748
|
free(path);
|
724
|
749
|
return false;
|
725
|
750
|
}
|
|
@@ -729,7 +754,7 @@ bool light_ctrl_exist(char const *controller)
|
729
|
754
|
if (!light_ctrl_get_brightnessPath(controller, &path))
|
730
|
755
|
return false;
|
731
|
756
|
|
732
|
|
- if (ctx.cmd != LIGHT_GET &&
|
|
757
|
+ if (ctx.cmd != LIGHT_GET && ctx.cmd != LIGHT_SAVE &&
|
733
|
758
|
ctx.field != LIGHT_MIN_CAP && !light_file_is_writable(path)) {
|
734
|
759
|
LIGHT_WARN("could not open controller brightness file for writing, so controller is not accessible");
|
735
|
760
|
free(path);
|
|
@@ -933,7 +958,7 @@ bool light_ctrl_save_brightness(char const *controller, unsigned long val)
|
933
|
958
|
return false;
|
934
|
959
|
}
|
935
|
960
|
|
936
|
|
- LIGHT_NOTE("saving brightness %lu (raw) to save file\n", val);
|
|
961
|
+ LIGHT_NOTE("saving brightness %lu (raw) to save file %s\n", val, path);
|
937
|
962
|
if (!light_file_write_val(path, val)) {
|
938
|
963
|
LIGHT_ERR("could not write to save/restore file");
|
939
|
964
|
free(path);
|
|
@@ -954,7 +979,7 @@ bool light_ctrl_restore_brightness(char const *controller)
|
954
|
979
|
return false;
|
955
|
980
|
}
|
956
|
981
|
|
957
|
|
- LIGHT_NOTE("restoring brightness from saved file");
|
|
982
|
+ LIGHT_NOTE("restoring brightness from saved file %s", path);
|
958
|
983
|
if (!light_file_read_val(path, &val)) {
|
959
|
984
|
LIGHT_ERR("could not read saved value");
|
960
|
985
|
free(path);
|