/** 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 . */ #include //printf #include //strcmp, strlen #include #include //getpwnam #include //getpwnam #include //chdir #include //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); }