Browse Source

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 years ago
parent
commit
7519c744cf
4 changed files with 52 additions and 21 deletions
  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 View File

185
 This installs the file `90-backlight.rules` into `/lib/udev/rules.d/`.
185
 This installs the file `90-backlight.rules` into `/lib/udev/rules.d/`.
186
 If your udev rules are located elsewhere, use `--with-udev=PATH`.
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
 Origin & References
193
 Origin & References

+ 1
- 1
src/Makefile.am View File

1
 bin_PROGRAMS   = light
1
 bin_PROGRAMS   = light
2
 light_SOURCES  = main.c light.c light.h helpers.c helpers.h
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
 light_CFLAGS   = -W -Wall -Wextra -std=gnu99 -Wno-type-limits
4
 light_CFLAGS   = -W -Wall -Wextra -std=gnu99 -Wno-type-limits
5
 
5
 
6
 if CLASSIC
6
 if CLASSIC

+ 43
- 18
src/light.c View File

1
 #include "light.h"
1
 #include "light.h"
2
 
2
 
3
+#include <libgen.h>
3
 #include <stdlib.h>
4
 #include <stdlib.h>
4
 #include <stdio.h>
5
 #include <stdio.h>
5
 #include <string.h>
6
 #include <string.h>
281
 	return true;
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
 bool light_initialize(int argc, char **argv)
302
 bool light_initialize(int argc, char **argv)
285
 {
303
 {
286
 	light_cmd_t mode;
304
 	light_cmd_t mode;
287
 	int rc;
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
 	light_defaults();
313
 	light_defaults();
290
 	if (!light_parse_args(argc, argv)) {
314
 	if (!light_parse_args(argc, argv)) {
291
 		LIGHT_ERR("could not parse arguments");
315
 		LIGHT_ERR("could not parse arguments");
297
 	if (mode == LIGHT_PRINT_HELP || mode == LIGHT_PRINT_VERSION || mode == LIGHT_LIST_CTRL)
321
 	if (mode == LIGHT_PRINT_HELP || mode == LIGHT_PRINT_VERSION || mode == LIGHT_LIST_CTRL)
298
 		return true;
322
 		return true;
299
 
323
 
324
+	/* Make sure we have a valid cache directory for all files */
300
 	if (mode == LIGHT_SAVE || (mode == LIGHT_SET && ctx.field == LIGHT_MIN_CAP)) {
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
 			if (rc && errno != EEXIST) {
336
 			if (rc && errno != EEXIST) {
311
 				LIGHT_ERR("'%s' does not exist and could not be created,"
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
 				return false;
339
 				return false;
314
 			}
340
 			}
315
-			++dir;
316
 		}
341
 		}
317
 	}
342
 	}
318
 
343
 
584
 			break;
609
 			break;
585
 
610
 
586
 		case LIGHT_MIN_CAP:
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
 			break;
613
 			break;
589
 
614
 
590
 		case LIGHT_SAVERESTORE:
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
 			break;
617
 			break;
593
 		}
618
 		}
594
 	} else {
619
 	} else {
602
 			break;
627
 			break;
603
 
628
 
604
 		case LIGHT_MIN_CAP:
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
 			break;
631
 			break;
607
 
632
 
608
 		case LIGHT_SAVERESTORE:
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
 			break;
635
 			break;
611
 		}
636
 		}
612
 	}
637
 	}
718
 		if (!light_ctrl_get_brightness_maxPath(controller, &path))
743
 		if (!light_ctrl_get_brightness_maxPath(controller, &path))
719
 			return false;
744
 			return false;
720
 		if (!light_file_is_readable(path)) {
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
 			free(path);
748
 			free(path);
724
 			return false;
749
 			return false;
725
 		}
750
 		}
729
 	if (!light_ctrl_get_brightnessPath(controller, &path))
754
 	if (!light_ctrl_get_brightnessPath(controller, &path))
730
 		return false;
755
 		return false;
731
 
756
 
732
-	if (ctx.cmd != LIGHT_GET &&
757
+	if (ctx.cmd != LIGHT_GET && ctx.cmd != LIGHT_SAVE &&
733
 	    ctx.field != LIGHT_MIN_CAP && !light_file_is_writable(path)) {
758
 	    ctx.field != LIGHT_MIN_CAP && !light_file_is_writable(path)) {
734
 		LIGHT_WARN("could not open controller brightness file for writing, so controller is not accessible");
759
 		LIGHT_WARN("could not open controller brightness file for writing, so controller is not accessible");
735
 		free(path);
760
 		free(path);
933
 		return false;
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
 	if (!light_file_write_val(path, val)) {
962
 	if (!light_file_write_val(path, val)) {
938
 		LIGHT_ERR("could not write to save/restore file");
963
 		LIGHT_ERR("could not write to save/restore file");
939
 		free(path);
964
 		free(path);
954
 		return false;
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
 	if (!light_file_read_val(path, &val)) {
983
 	if (!light_file_read_val(path, &val)) {
959
 		LIGHT_ERR("could not read saved value");
984
 		LIGHT_ERR("could not read saved value");
960
 		free(path);
985
 		free(path);

+ 5
- 2
src/light.h View File

60
 } light_val_mode_t;
60
 } light_val_mode_t;
61
 
61
 
62
 typedef struct {
62
 typedef struct {
63
+	/* Cache file prefix */
64
+	char               prefix[NAME_MAX + 1];
65
+
63
 	/* Which controller to use */
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
 	/* What to do with the controller */
70
 	/* What to do with the controller */
68
 	light_cmd_t        cmd;
71
 	light_cmd_t        cmd;