소스 검색

Fix #46: Migrate to use ~/.cache/light for unpriviliged operation

When light is installed in the non-SUID root mode it cannot write to
/etc/light anymore, so we set up a ~/.cache/light instead.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Joachim Nilsson 6 년 전
부모
커밋
7519c744cf
4개의 변경된 파일52개의 추가작업 그리고 21개의 파일을 삭제
  1. 3
    0
      README.md
  2. 1
    1
      src/Makefile.am
  3. 43
    18
      src/light.c
  4. 5
    2
      src/light.h

+ 3
- 0
README.md 파일 보기

@@ -185,6 +185,9 @@ configure script to enable this mode of operation:
185 185
 This installs the file `90-backlight.rules` into `/lib/udev/rules.d/`.
186 186
 If your udev rules are located elsewhere, use `--with-udev=PATH`.
187 187
 
188
+Note, in this mode `light` runs unpriviliged, so the `/etc/light`
189
+directory (for cached settings) is not used, instead the per-user
190
+specific `~/.cache/light` is used.
188 191
 
189 192
 
190 193
 Origin & References

+ 1
- 1
src/Makefile.am 파일 보기

@@ -1,6 +1,6 @@
1 1
 bin_PROGRAMS   = light
2 2
 light_SOURCES  = main.c light.c light.h helpers.c helpers.h
3
-light_CPPFLAGS = -I../include -D_XOPEN_SOURCE=500
3
+light_CPPFLAGS = -I../include -D_GNU_SOURCE
4 4
 light_CFLAGS   = -W -Wall -Wextra -std=gnu99 -Wno-type-limits
5 5
 
6 6
 if CLASSIC

+ 43
- 18
src/light.c 파일 보기

@@ -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);

+ 5
- 2
src/light.h 파일 보기

@@ -60,9 +60,12 @@ typedef enum {
60 60
 } light_val_mode_t;
61 61
 
62 62
 typedef struct {
63
+	/* Cache file prefix */
64
+	char               prefix[NAME_MAX + 1];
65
+
63 66
 	/* Which controller to use */
64
-	light_ctrl_mode_t ctrl;
65
-	char              ctrl_name[NAME_MAX + 1];
67
+	light_ctrl_mode_t  ctrl;
68
+	char               ctrl_name[NAME_MAX + 1];
66 69
 
67 70
 	/* What to do with the controller */
68 71
 	light_cmd_t        cmd;