summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@oper.io>2017-12-31 15:44:20 -0700
committerAaron Ball <nullspoon@oper.io>2017-12-31 15:44:20 -0700
commit037736c60d3361b1acae57ed1e8913ba0ac4c9b7 (patch)
tree079c452426ad3a522e848512bcd2e185e4961b11
parent4b5f62be49769842ce2e91cf6455c219280e31fc (diff)
parentf95b9f6f6c7f83dcb9aef2b4191ace55dcb47789 (diff)
downloadluminous-037736c60d3361b1acae57ed1e8913ba0ac4c9b7.tar.gz
luminous-037736c60d3361b1acae57ed1e8913ba0ac4c9b7.tar.xz
Merge branch 'config'v1.1-rc1
-rw-r--r--Makefile15
-rw-r--r--sample.conf3
-rw-r--r--src/config.c231
-rw-r--r--src/config.h37
-rw-r--r--src/main.c78
5 files changed, 349 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index f4b2ef8..15186c0 100644
--- a/Makefile
+++ b/Makefile
@@ -3,13 +3,22 @@ CCOPTS=-Wall
BINDIR=/usr/bin
INITDIR=/etc/rc.d
+CONFDIR=/etc/
all:
- cc $(CCOPTS) $(DBG) src/main.c -o luminous
+ if [ ! -d obj ]; then mkdir obj; fi
+ cc $(CCOPTS) $(DBG) src/config.c -c -o obj/config.o
+ cc $(CCOPTS) $(DBG) obj/*.o src/main.c -o luminous
install:
- install -D luminous ${DESTDIR}/${BINDIR}/luminous
- install -D init.sh ${DESTDIR}/${INITDIR}/luminous
+ install -D luminous ${DESTDIR}/${BINDIR}/luminous
+ install -D init.sh ${DESTDIR}/${INITDIR}/luminous
+ install -D sample.conf ${DESTDIR}/${CONFDIR}/luminous.conf
debug:
make DBG=-g
+
+leak-test:
+ make debug
+ valgrind --error-exitcode=1 luminous -l 800 && printf "\n\n--- No leaks found!\n\n"
+ valgrind --error-exitcode=1 luminous -l 150 && printf "\n\n--- No leaks found!\n\n"
diff --git a/sample.conf b/sample.conf
new file mode 100644
index 0000000..da257f9
--- /dev/null
+++ b/sample.conf
@@ -0,0 +1,3 @@
+level = 150
+rate = 20
+step = 12
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..1ff9a2b
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,231 @@
+/**
+ * Copyright (C) 2017 Aaron Ball <nullspoon@oper.io>
+ *
+ * Luminous 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.
+ *
+ * Luminous 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 noteless. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+
+
+/**
+ * config_new:
+ * @c Config struct to initialize
+ * @path Path to the config file to initialize from (only used by config_load)
+ *
+ * Config struct constructor.
+ *
+ * Returns success (0) or failure (-1). Failure occurs when specified config
+ * file is not accessible or could not be found.
+ */
+int config_new(struct config* c, const char* path) {
+ FILE* fd;
+
+ // Check if the config file exists
+ fd = fopen(path, "r");
+ if(!fd)
+ return -1;
+ fclose(fd);
+
+ c->count = 0;
+ c->path = path;
+ c->keys = malloc(0);
+ c->vals = malloc(0);
+ return 0;
+}
+
+
+/**
+ * line_get_key:
+ * @line Line to search for key in
+ * @start Pointer to integer holding substring start index
+ * @end Pointer to integer holding substring end index
+ *
+ * Searches the specified string for a key (preceeding an '=' delimiter).
+ *
+ * Returns Length of found key, otherwise -1.
+ */
+int line_get_key(char* line, int* start, int* end) {
+ *start = 0;
+ *end = 0;
+
+ // Find beginning of key, allowing for preceeding whitespace
+ while(line[*start] == ' ' && line[*start] != '\0')
+ *start = *start + 1;
+
+ // Return error if no non-whitespace text was found
+ if(line[*start] == '\0')
+ return -1;
+
+ *end = *start;
+
+ // Find the end of the key
+ while(line[*end] != ' ' && line[*end] != '=' && line[*end] != '\0')
+ *end = *end + 1;
+
+ return *end - *start;
+}
+
+
+/**
+ * line_get_val:
+ * @line Line to search for value in
+ * @start Pointer to integer holding substring start index
+ * @end Pointer to integer holding substring end index
+ *
+ * Searches the specified string for a value (following an '=' delimiter).
+ *
+ * Returns Length of found value, otherwise -1.
+ */
+int line_get_val(char* line, int* start, int* end) {
+ *start = 0;
+ *end = 0;
+
+ // Find beginning of key, allowing for preceeding whitespace
+ // Set the start cursor to the first non-whitespace character after the
+ // equals sign
+ while(line[*start] != '=' && line[*start] != '\0')
+ *start = *start + 1;
+
+ // Advance one to pass the equals sign
+ *start = *start + 1;
+
+ // A seperate loop to handle leading whitespace. Having this outside of the
+ // previous loop prevents us from allowing for multiple contiguous equals
+ // signs
+ while(line[*start] == ' ')
+ *start = *start + 1;
+
+ // Return error if no equals sign was found
+ if(line[*start] == '\0')
+ return -1;
+
+ // Find the end of the string, not including the newline char if one is
+ // present (this is why we don't use strlen, becuase it includes the index of
+ // the newline char if one is present)
+ while(line[*end] != '\n' && line[*end] != '\0')
+ *end = *end + 1;
+
+ return *end - *start;
+}
+
+
+/**
+ * config_load:
+ * @c Config struct to load config data into
+ *
+ * Returns number of config items found in the config file
+ */
+int config_load(struct config* c) {
+ // Values for tracking config line component start and end indexes
+ int keystart = 0, keyend = 0, keylen = 0;
+ int valstart = 0, valend = 0, vallen = 0;
+ char buf[512]; // Config line buffer
+ FILE* fd; // Config file descriptor
+
+ fd = fopen(c->path, "r");
+
+ while(fgets(buf, 512, fd) != NULL) {
+ c->count++;
+
+ // Allocate array space for new keys and values
+ c->keys = realloc(c->keys, sizeof(char*) * c->count);
+ c->vals = realloc(c->vals, sizeof(char*) * c->count);
+
+ // Get the key start and end index
+ keylen = line_get_key(buf, &keystart, &keyend);
+ // Allocate space for new key
+ c->keys[c->count - 1] = malloc(keylen + 1);
+ // Copy the key into the new memory
+ strncpy(c->keys[c->count - 1], &buf[keystart], keylen);
+ // Dont' forget the null byte!
+ c->keys[c->count - 1][keylen] = '\0';
+
+ // Do the exact same thing for the value
+ vallen = line_get_val(buf, &valstart, &valend);
+ c->vals[c->count - 1] = malloc(vallen + 1);
+ strncpy(c->vals[c->count - 1], &buf[valstart], vallen);
+ c->vals[c->count - 1][vallen] = '\0';
+
+ // Reset our index variables
+ keystart = 0, keyend = 0, keylen = 0;
+ valstart = 0, valend = 0, vallen = 0;
+ }
+
+ fclose(fd);
+
+ return c->count;
+}
+
+
+/**
+ * config_dump:
+ * @c Config struct to dump
+ * @fd File descriptor to print dump text to. If NULL, prints to stdout
+ *
+ * Dumps the provided config struct to the specified file descriptor.
+ */
+void config_dump(struct config* c, FILE* fd) {
+ int i = 0;
+ if(!fd)
+ fd = stdout;
+
+ while(i < c->count) {
+ fprintf(fd, "%d %s %s\n", i, c->keys[i], c->vals[i]);
+ i++;
+ }
+}
+
+
+/**
+ * config_get:
+ * @c Config struct to search for a matching key
+ * @key Config key to find value for
+ * @out Output buffer to copy value to
+ *
+ * Returns Status integer (0 == key found, -1 == key not found)
+ */
+int config_get(struct config* c, char* key, char* out) {
+ int i = 0;
+
+ while(i < c->count) {
+ // Copy value for matching key to output buffer
+ if(strcmp(c->keys[i], key) == 0) {
+ strcpy(out, c->vals[i]);
+ return 0;
+ }
+ i++;
+ }
+
+ // If we reach this point, no matching keys were found
+ return -1;
+}
+
+
+/**
+ * config_free:
+ * @c Config struct to free
+ */
+int config_free(struct config* c) {
+ while(c->count > 0) {
+ // Free the corresponding
+ free(c->keys[c->count - 1]);
+ free(c->vals[c->count - 1]);
+ c->count--;
+ }
+
+ // Free the array space
+ free(c->keys);
+ free(c->vals);
+
+ return 0;
+}
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..247efb3
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2017 Aaron Ball <nullspoon@oper.io>
+ *
+ * Luminous 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.
+ *
+ * Luminous 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 noteless. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct config {
+ const char* path;
+ int count; // Number of config entries
+ char** keys;
+ char** vals;
+};
+
+
+int config_new(struct config*, const char*);
+
+int config_load(struct config*);
+
+void config_dump(struct config*, FILE*);
+
+int config_get(struct config*, char*, char*);
+
+int config_free(struct config*);
diff --git a/src/main.c b/src/main.c
index be7bd29..f3ab73a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,6 +20,10 @@
#include <time.h>
#include <errno.h>
+#include "config.h"
+
+#define CONF "/etc/luminous.conf"
+
struct props {
int lvl;
@@ -32,6 +36,17 @@ struct props {
};
+void props_new(struct props* p) {
+ p->lvl = -1;
+ p->step = -1;
+ p->rate = -1;
+ p->max = -1;
+ p->cur = -1;
+ p->filebrightness[0] = '\0';
+ p->filemax_bright[0] = '\0';
+}
+
+
/**
* fgeti:
* @path
@@ -183,7 +198,7 @@ void usage() {
* returns: Success (0), failure (-1), or incomplete (-2)
*/
int parseargs(struct props* out, int argc, char* argv[]) {
- int i = 0;
+ int i;
strcpy(out->filebrightness,
"/sys/class/backlight/intel_backlight/brightness");
@@ -194,11 +209,7 @@ int parseargs(struct props* out, int argc, char* argv[]) {
out->cur = fgeti(out->filebrightness);
out->max = fgeti(out->filemax_bright);
- // Some defaults
- out->rate = 10;
- out->step = 8;
-
- for(;i < argc; i++) {
+ for(i = 0; i < argc; i++) {
if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--rate") == 0) {
i++;
out->rate = atoi(argv[i]);
@@ -221,6 +232,14 @@ int parseargs(struct props* out, int argc, char* argv[]) {
}
}
+ // Some defaults, if no values are set yet
+ if(out->rate < 0)
+ out->rate = 20;
+ if(out->step < 0)
+ out->step = 12;
+ if(out->lvl == -1)
+ out->lvl = 200;
+
// Ensure min and max thresholds are respected
if(out->lvl > out->max) {
out->lvl = out->max;
@@ -231,6 +250,38 @@ int parseargs(struct props* out, int argc, char* argv[]) {
}
+int config_to_props(char* confpath, struct props* p) {
+ struct config c;
+ char lvlbuf[32]; // Buffer to store config value for "level" if found
+ char ratebuf[32]; // Buffer to store config value for "rate" if found
+ char stepbuf[32]; // Buffer to store config value for "step" if found
+
+ if(config_new(&c, confpath) == 0) {
+ config_load(&c);
+ } else {
+ // Config file not found, return -2 code
+ return -2;
+ }
+
+ // If the config specifies a "level" key, set it to the props object
+ if(config_get(&c, "level", lvlbuf) == 0)
+ p->lvl = atoi(lvlbuf);
+
+ // If the config specifies a "step" key, set it to the props object
+ if(config_get(&c, "step", stepbuf) == 0)
+ p->step = atoi(stepbuf);
+
+ // If the config specifies a "rate" key, set it to the props object
+ if(config_get(&c, "rate", ratebuf) == 0)
+ p->rate = atoi(ratebuf);
+
+ // Don't forget to clean up!
+ config_free(&c);
+
+ return 0;
+}
+
+
/**
* Ye olde main
*/
@@ -238,16 +289,19 @@ int main(int argc, char* argv[]) {
int r = 0;
struct props p;
+ props_new(&p);
+
+ // Load configs into properties struct
+ config_to_props(CONF, &p);
+
+ // Parse cli arguments (overriding any configs if specified at runtime)
if(parseargs(&p, argc, argv) != 0)
return 1;
- if(argc == 1) {
- printf("%d\n", p.cur);
- return 0;
- }
-
// Determine if we should fade up or fade down
- if(p.lvl > p.cur) {
+ if(p.lvl < 0) {
+ printf("%d\n", p.cur);
+ } else if(p.lvl > p.cur) {
r = fadeup(&p);
} else if (p.lvl < p.cur) {
r = fadedown(&p);

Generated by cgit