From 3299a6805991b57409e1d3b72071b62dd4f728e6 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Wed, 7 Oct 2020 21:06:41 +0200 Subject: [PATCH] initiated commitment --- .gitignore | 6 + LICENSE | 25 ++++ README.md | 27 ++++ makefile | 25 ++++ sbl.1 | 0 sbl.c | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 444 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 makefile create mode 100644 sbl.1 create mode 100644 sbl.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..999ee82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +**/*.o +sbl* +tests/** +!**/*.c +!**/*.1 + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a0f7ec4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ + GLWT(Good Luck With That) Public License + Copyright (c) Everyone, except Author + +Everyone is permitted to copy, distribute, modify, merge, sell, publish, +sublicense or whatever they want with this software but at their OWN RISK. + + Preamble + +The author has absolutely no clue what the code in this project does. +It might just work or not, there is no third option. + + + GOOD LUCK WITH THAT PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION + + 0. You just DO WHATEVER YOU WANT TO as long as you NEVER LEAVE A +TRACE TO TRACK THE AUTHOR of the original product to blame for or hold +responsible. + +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +Good luck and Godspeed. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3cc406f --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Simple backlight +Simple utility to change the backlight + +## Features +- Set the monitor to change +- Save and restore backlight +- Written in C99, that is a pro i guess... + +## Getting +Clone this repository, then use `make` to compile, `make install` and `make +uninstall` to install and uninstall, finally `make clean` to remove all the +compiled junk from the folder. + +## Usage +Here are some examples: + +```sh +# Increase brightness by 10% and save the changed brightness to $HOME/.savefile +$ sbl -c $HOME/.savefile -S -i 10 +# Set the brightness to 30% +$ sbl -s 30 +# Restore the saved backlight value from example 1 +$ sbl -c $HOME/.savefile -r +# Forgot what does what? +$ sbl -h +``` +Read the man page for detailed instructions diff --git a/makefile b/makefile new file mode 100644 index 0000000..737f6d9 --- /dev/null +++ b/makefile @@ -0,0 +1,25 @@ +CC ?= gcc +CFLAGS = -Wall -pedantic --std=c99 -O2 +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +sbl: sbl.c + +dbg: + gcc -O0 -g sbl.c -o sbl-dbg + +install: sbl + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f sbl ${DESTDIR}${PREFIX}/bin/sbl + chown root:root ${DESTDIR}${PREFIX}/bin/sbl + chmod 4755 ${DESTDIR}${PREFIX}/bin/sbl + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + cp -f sbl.1 ${DESTDIR}${MANPREFIX}/man1/sbl.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/sbl.1 + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/sbl\ + ${DESTDIR}${MANPREFIX}/man1/sbl.1 + +clean: + rm -f sbl sbl-dbg diff --git a/sbl.1 b/sbl.1 new file mode 100644 index 0000000..e69de29 diff --git a/sbl.c b/sbl.c new file mode 100644 index 0000000..e242761 --- /dev/null +++ b/sbl.c @@ -0,0 +1,361 @@ +#define _DEFAULT_SOURCE +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BACKLIGHT_ROOT_PATH "/sys/class/backlight/" +#define BL_MIN 5 + +#define const_arr_size(val) ((int)(sizeof(val)/sizeof(val[0]))) + +const char *savefile_paths[] = { + NULL, /* reserved for external savefile path */ + "/etc/sbl/savefile" +}; + +enum action { + DISPLAY, INCREASE, DECREASE, SET, RESTORE +}; + +static uid_t ruid; +int device_index = 0; + +static void die (const char *, ...); +static void usage (void); +static void list_cards (void); +static void set_brightness (float); +static void change_permissions (const char *); +static void restore_permissions (void); +static int save_value (float); +static int get_max_brightness (void); +static float get_saved_value (void); +static float get_current_brightness (void); +static const char * backlight_path (int); +static const char * get_savefile (void); + +int main (int argc, char *argv[]) +{ + int opc = 0, store = 0; + enum action act = DISPLAY; + float value = BL_MIN; + char *extfile = NULL; + /* Parse command line arguments */ + while ((opc = getopt(argc, argv, "c:hI:li:d:s:Sr")) != -1) { + switch (opc) { + case 'l': + list_cards(); + break; + case 'h': + usage(); + break; + case 'c': + extfile = malloc(strlen(optarg) + 1); + if (!extfile) + die("malloc in main():"); + strcpy(extfile, optarg); + savefile_paths[0] = extfile; + break; + case 'I': + device_index = atoi(optarg); + break; + case 'i': + act = INCREASE; + value = atof(optarg); + break; + case 'd': + act = DECREASE; + value = atof(optarg); + break; + case 's': + act = SET; + value = atof(optarg); + break; + case 'r': + act = RESTORE; + break; + case 'S': + store = 1; + break; + default: + exit(EXIT_FAILURE); + break; + } + } + + ruid = getuid (); + + switch (act) { + case DISPLAY: + printf("%.2f\n", get_current_brightness()); + break; + case SET: + set_brightness(value); + break; + case INCREASE: + value += get_current_brightness(); + set_brightness(value); + break; + case DECREASE: + value = get_current_brightness() - value; + set_brightness(value); + break; + case RESTORE: + set_brightness(get_saved_value()); + break; + default: + break; + } + + if (store) + save_value(get_current_brightness()); + + if (extfile) + free(extfile); + return 0; +} + +int save_value (float value) +{ + FILE *fd; + fd = fopen(get_savefile(), "w"); + if (!fd) + die("could not open savefile"); + fprintf(fd, "%f\n", value); + fclose(fd); + return 1; +} + +float get_saved_value (void) +{ + FILE *fd; + float rtf = -1; + fd = fopen(get_savefile(), "r"); + if (!fd) + die("could not open savefile"); + fscanf(fd, "%f", &rtf); + fclose(fd); + return rtf; +} + +float get_current_brightness (void) +{ + FILE *fd; + char buf[PATH_MAX] = {0}; + int cb = -1; + const char *path = backlight_path(device_index); + if (!path) + die("invalid device index"); + strcpy(buf, path); + strcat(buf, "/brightness"); + fd = fopen(buf, "r"); + if (!fd) + die("could not open %s", buf); + fscanf(fd, "%d", &cb); + fclose(fd); + + return ((float)cb / (float)get_max_brightness()) * 100.0;; +} + +int get_max_brightness (void) +{ + FILE *fd; + char buf[PATH_MAX] = {0}; + int rti = -1; + const char *path = backlight_path(device_index); + if (!path) + die("invalid device index"); + strcpy(buf, path); + strcat(buf, "/max_brightness"); + fd = fopen(buf, "r"); + if (!fd) + die("could not open %s", buf); + fscanf(fd, "%d", &rti); + fclose(fd); + + return rti; +} + +/* Return the correct savefile path, creating it if it does not exist */ +const char * get_savefile (void) +{ + static char buf[PATH_MAX]; + wordexp_t result = {0}; + FILE *fd; + + for (int i = 0; i < const_arr_size(savefile_paths); i++) { + if (!savefile_paths[i]) + continue; + switch (wordexp(savefile_paths[i], &result, 0)) { + case 0: + break; + case WRDE_NOSPACE: + wordfree (&result); + die("Not enough space"); + default: + die("Path not valid"); + } + + strcpy(buf, result.we_wordv[0]); + if ((fd = fopen(result.we_wordv[0], "r"))) + break; + } + /* Create a savefile */ + if (!fd) { + wordfree(&result); + for (int i = 0; i < const_arr_size(savefile_paths); i++) { + if (!savefile_paths[i]) + continue; + switch (wordexp(savefile_paths[i], &result, 0)) { + case 0: + break; + case WRDE_NOSPACE: + wordfree (&result); + die("Not enough space"); + default: + die("Path not valid"); + } + + strcpy(buf, result.we_wordv[0]); + if ((fd = fopen(result.we_wordv[0], "w"))) + break; + } + } + wordfree(&result); + if (!fd) + die("could not open or create a savefile"); + fclose(fd); + return buf; +} + +const char * backlight_path (int index) +{ + DIR *dp; + struct dirent *de; + static char buf[PATH_MAX]; + + memset(buf, 0, PATH_MAX); + if (index < 0) + die("%d is not a valid index", index); + if (!(dp = opendir(BACKLIGHT_ROOT_PATH))) + die("error opening " BACKLIGHT_ROOT_PATH); + + errno = 0; + while ((de = readdir(dp))) { + if (!(de->d_type & DT_LNK)) + continue; + if (index) { + index--; + continue; + } else { + strcpy(buf, BACKLIGHT_ROOT_PATH); + strcat(buf, de->d_name); + break; + } + } + closedir(dp); + if (errno) + die("error reading " BACKLIGHT_ROOT_PATH); + // FIXME: actually check return value of this + if (!buf[0]) + return NULL; + return buf; + +} + +void list_cards (void) +{ + int i = 0; + const char *s; + for (; (s = backlight_path(i)); i++) + printf("%d: %s\n", i, s); + exit(EXIT_SUCCESS); +} + +void set_brightness (float value) +{ + int set; + char buf[PATH_MAX] = {0}; + const char *path = backlight_path(device_index); + FILE *fd; + if (value > 100) + value = 100; + if (value < BL_MIN) + value = BL_MIN; + set = (value/100.0) * get_max_brightness(); + if (set < 0) + return; + if (!path) + die("invalid device index"); + strcpy(buf, path); + strcat(buf, "/brightness"); + change_permissions(buf); + fd = fopen(buf, "w"); + if (!fd) + die("could not open %s", buf); + fprintf(fd, "%d", set); + fclose(fd); + restore_permissions(); +} + +/* Change the process permissions matching the ones pointed by path */ +void change_permissions (const char *path) +{ + int status; + struct stat st; + + stat(path, &st); + status = seteuid(st.st_uid); + if (status < 0) + die("could not setuid"); +} + +static void restore_permissions (void) +{ + int status; + status = seteuid(ruid); + if (status < 0) + die("could not setuid"); +} + +void die(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + vfprintf(stderr, fmt, ap); + + if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + va_end(ap); + exit(errno ? errno : 1); +} + +static void usage (void) +{ + puts("Usage: sbl [-hlrS] [-c savefile] [-I index] [-i/d/s percent]\n" + "-h print this message\n" + "-l list devices by index\n" + "-r restore saved value\n" + "-S save value\n" + "-c savefile specify savefile\n" + "-I index specify device by index\n" + "-i percent increase backlight by percent\n" + "-d percent decrease backlight by percent\n" + "-s percent set backlight to percent\n"); + exit(EXIT_SUCCESS); +}