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