160 lines
4.2 KiB
C
160 lines
4.2 KiB
C
/**
|
|
rexbacklight
|
|
Copyright (C) 2018 rexy712
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdio.h> //printf
|
|
#include <string.h> //strcmp, strlen
|
|
#include <rjp.h>
|
|
#include <sys/types.h> //getpwnam
|
|
#include <pwd.h> //getpwnam
|
|
#include <unistd.h> //chdir
|
|
#include <stdlib.h> //malloc, free
|
|
|
|
#include "restore.h"
|
|
#include "common.h"
|
|
#include "cmd.h"
|
|
#include "globals.h"
|
|
#include "rexbacklight.h"
|
|
|
|
static char* get_home_folder(void){
|
|
char* user = getenv("SUDO_USER");
|
|
char* home = getenv("HOME");
|
|
if(!home || user){
|
|
if(!user){
|
|
return NULL;
|
|
}
|
|
struct passwd* pw_entry = getpwnam(user);
|
|
if(!pw_entry){
|
|
return NULL;
|
|
}
|
|
home = pw_entry->pw_dir;
|
|
}
|
|
return home;
|
|
}
|
|
static char* restore_file(void){
|
|
char* home_folder = get_home_folder();
|
|
if(!home_folder)
|
|
return NULL;
|
|
|
|
//"/.config/rexbacklight.json"
|
|
size_t home_folder_len = strlen(home_folder);
|
|
size_t conf_len = strlen(restore_file_suffix());
|
|
char* rest_file = malloc(home_folder_len + conf_len + 1);
|
|
strncpy(rest_file, home_folder, home_folder_len);
|
|
strncpy(rest_file+home_folder_len, restore_file_suffix(), conf_len);
|
|
rest_file[home_folder_len+conf_len] = 0;
|
|
return rest_file;
|
|
}
|
|
|
|
RJP_value* read_restore_file(const char* file){
|
|
size_t filesize;
|
|
char* file_contents;
|
|
int i;
|
|
FILE* fp = fopen(file, "r");
|
|
if(!fp){
|
|
fprintf(stderr, "Could not restore! No restore file found!\n");
|
|
return NULL;
|
|
}
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
filesize = ftell(fp);
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
file_contents = malloc(filesize+1);
|
|
i = fread(file_contents, filesize, 1, fp);
|
|
fclose(fp);
|
|
file_contents[filesize] = 0;
|
|
RJP_value* root = rjp_parse(file_contents);
|
|
free(file_contents);
|
|
return root;
|
|
}
|
|
|
|
RJP_value* find_matching_json_device(const char* name, RJP_value* root){
|
|
for(RJP_value* curr = rjp_get_member(root);curr;curr = rjp_next_member(curr)){
|
|
if(!strcmp(rjp_member_name(curr), name)){
|
|
return curr;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//convert a restoration operation to a set operation
|
|
int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore){
|
|
if(!*root && *try_restore){
|
|
char* tmp = restore_file();
|
|
*root = read_restore_file(tmp);
|
|
free(tmp);
|
|
if(!*root){
|
|
*try_restore = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
RJP_value* match = find_matching_json_device(curr->device, *root);
|
|
if(!match){
|
|
fprintf(stderr, "No matching device '%s' in restore file!\n", curr->device);
|
|
return 0;
|
|
}
|
|
curr->operation = OP_SET;
|
|
curr->delta = rjp_value_dfloat(match);
|
|
return 1;
|
|
}
|
|
|
|
void save_restore_file(struct string_array* devices){
|
|
RJP_value* root = rjp_init_json();
|
|
for(size_t i = 0;i < devices->size;++i){
|
|
if(chdir(devices->list[i])){
|
|
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), devices->list[i]);
|
|
return_value = RETVAL_INVALID_DIR;
|
|
continue;
|
|
}
|
|
size_t esc_name_len = rjp_escape_strlen(devices->list[i]);
|
|
char* esc_str = rjp_alloc(esc_name_len + 1);
|
|
rjp_escape_strcpy(esc_str, devices->list[i]);
|
|
|
|
float curr = get_brightness(brightness_file());
|
|
float max = get_brightness(max_brightness_file());
|
|
if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){
|
|
rjp_add_member(root, 0, esc_str, 0, rjp_null());
|
|
}else{
|
|
rjp_add_member(root, 0, esc_str, 0, rjp_dfloat(curr/max*100));
|
|
}
|
|
|
|
if(chdir(device_dir())){
|
|
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
|
|
return_value = RETVAL_INVALID_DIR;
|
|
rjp_free_value(root);
|
|
free(esc_str);
|
|
return;
|
|
}
|
|
}
|
|
char* tmp = rjp_to_json(root);
|
|
char* rfil = restore_file();
|
|
FILE* restf = fopen(rfil, "w");
|
|
if(!restf){
|
|
io_error(IO_ERROR_OPEN, IO_ERROR_FILE, rfil);
|
|
}else{
|
|
fprintf(restf, "//File generated by %s\n%s\n", executable_name(), tmp);
|
|
fclose(restf);
|
|
}
|
|
free(rfil);
|
|
rjp_free(tmp);
|
|
rjp_free_value(root);
|
|
}
|
|
|
|
|
|
|