diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | config.def.h | 7 | ||||
-rw-r--r-- | cqrlogo.c | 83 | ||||
-rw-r--r-- | cqrlogo.conf | 16 | ||||
-rw-r--r-- | cqrlogo.h | 12 |
6 files changed, 102 insertions, 25 deletions
@@ -11,9 +11,10 @@ SED := sed GREP := grep FILE := file CFLAGS += -O2 -Wall -Werror -CFLAGS += $(shell pkg-config --cflags --libs libpng) \ - $(shell pkg-config --cflags --libs zlib) \ - $(shell pkg-config --cflags --libs libqrencode) +CFLAGS += -liniparser +CFLAGS += $(shell pkg-config --cflags --libs libpng) +CFLAGS += $(shell pkg-config --cflags --libs zlib) +CFLAGS += $(shell pkg-config --cflags --libs libqrencode) VERSION := $(shell git describe --tags --long 2>/dev/null) # this is just a fallback in case you do not use git but downloaded # a release tarball... @@ -42,6 +43,7 @@ install: install-bin install-doc install-bin: cqrlogo $(INSTALL) -D -m0755 cqrlogo $(DESTDIR)$(PREFIX)/share/webapps/cqrlogo/cqrlogo + $(INSTALL) -D -m0644 cqrlogo.conf $(DESTDIR)/etc/cqrlogo.conf install-doc: README.html cqrlogo.png $(INSTALL) -D -m0644 README.md $(DESTDIR)$(PREFIX)/share/doc/cqrlogo/README.md @@ -14,6 +14,7 @@ Requirements To compile and run `cqrlogo` you need: +* [iniparser](http://ndevilla.free.fr/iniparser/) * [libpng](http://www.libpng.org/pub/png/libpng.html) * [zlib](http://www.zlib.net/) (which is a dependency for libpng) * [qrencode](http://megaui.net/fukuchi/works/qrencode/index.en.html) diff --git a/config.def.h b/config.def.h index 54f45b6..9712f30 100644 --- a/config.def.h +++ b/config.def.h @@ -8,6 +8,13 @@ #ifndef _CONFIG_H #define _CONFIG_H +/* path to the config file */ +#define CONFIGFILE "/etc/cqrlogo.conf" + +/* whether or not defaults or settings from config may be overwritten + * by query string */ +#define ALLOW_OVERWRITE 1 + /* pixels are scaled up by this factor */ #define QRCODE_SCALE 2 /* this is the maximum scale factor */ @@ -11,6 +11,7 @@ #include <inttypes.h> #include <regex.h> +#include <iniparser.h> #include <png.h> #include <zlib.h> #include <qrencode.h> @@ -27,11 +28,11 @@ /*** add_png_text ***/ png_text * add_png_text(png_text *pngtext, unsigned int *textcount, char *key, char *text) { pngtext = realloc(pngtext, ((*textcount) + 1) * sizeof(png_text)); - + pngtext[*textcount].compression = PNG_TEXT_COMPRESSION_zTXt; pngtext[*textcount].key = key; pngtext[*textcount].text = text; - + (*textcount)++; return pngtext; } @@ -60,7 +61,7 @@ int generate_png (struct bitmap_t *bitmap, const char *uri) { /* use best compression */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); - /* use compression strategy filtered + /* use compression strategy filtered * this way pngcrush can not optimize any more */ png_set_compression_strategy(png_ptr, Z_FILTERED); @@ -68,7 +69,7 @@ int generate_png (struct bitmap_t *bitmap, const char *uri) { unsigned int textcount = 0; png_text *pngtext = NULL; - pngtext = add_png_text(pngtext, &textcount, "comment", "QR-Code created by cqrlogo - https://github.com/eworm-de/cqrlogo"); + pngtext = add_png_text(pngtext, &textcount, "comment", "QR-Code created by cqrlogo - https://github.com/eworm-de/cqrlogo"); # if PNG_ENABLE_TEXT_REFERER pngtext = add_png_text(pngtext, &textcount, "referer", (char *)uri); # endif @@ -77,7 +78,7 @@ int generate_png (struct bitmap_t *bitmap, const char *uri) { # define VERSIONSTR VERSION " (" __DATE__ ", " __TIME__ ")" # define LIBSSTR "libqrencode %s, libpng %s, zlib %s" char *libsstr, *qrver = QRcode_APIVersionString(); - + libsstr = malloc(sizeof(LIBSSTR) + strlen(qrver) + strlen(png_libpng_ver) + strlen(zlib_version)); sprintf(libsstr, LIBSSTR, qrver, png_libpng_ver, zlib_version); @@ -148,7 +149,8 @@ void bitmap_free(struct bitmap_t * bitmap) { } /*** encode_qrcode ***/ -struct bitmap_t * encode_qrcode (const char *text, unsigned int scale, unsigned int border, unsigned int level) { +struct bitmap_t * encode_qrcode (const char *text, unsigned int scale, + unsigned int border, unsigned int level) { QRcode *qrcode; struct bitmap_t *bitmap, *scaled; int i, j, k, l; @@ -194,10 +196,12 @@ struct bitmap_t * encode_qrcode (const char *text, unsigned int scale, unsigned return scaled; } -/*** get_value ***/ -int get_value(const char *query_string, const char *pattern, unsigned int *value, unsigned int def, unsigned int min, unsigned int max) { +/*** get_query_value ***/ +unsigned int get_query_value(const char *query_string, const char *pattern, + unsigned int value, unsigned int min, unsigned int max) { char *match = NULL, *newpattern = NULL; unsigned int length; + int tmp = -1; newpattern = strdup(pattern); @@ -210,23 +214,46 @@ int get_value(const char *query_string, const char *pattern, unsigned int *value if ((match = strstr(query_string, newpattern)) != NULL) { sprintf(newpattern + length + 1, "%%u"); - if ((sscanf(match, newpattern, value)) > 0) - if (*value < min || *value > max) - *value = def; + if ((sscanf(match, newpattern, &tmp)) > 0) + if (tmp >= min && tmp <= max) + value = tmp; } free(newpattern); - return EXIT_SUCCESS; + return value; +} + +/*** get_ini_value ***/ +unsigned int get_ini_value(dictionary * ini, uint8_t type, const char * section, const char * parameter, + unsigned int value, unsigned int min, unsigned int max) { + char * key; + unsigned int tmp; + + key = malloc(strlen(section) + strlen(parameter) + 2); + sprintf(key, "%s:%s", section, parameter); + + if (type) + tmp = iniparser_getint(ini, key, value); + else + tmp = iniparser_getboolean(ini, key, value); + + if (tmp >= min && tmp <= max) + value = tmp; + + free(key); + + return value; } /*** main ***/ int main(int argc, char **argv) { + dictionary * ini; const char * http_referer, * server_name, * query_string, * uri; char * uri_server_name = NULL, * uri_png = NULL, * pattern = NULL, * stolen = NULL; regex_t preg; regmatch_t pmatch[1]; - unsigned int https = 0; + uint8_t https = 0, overwrite = ALLOW_OVERWRITE; struct bitmap_t * bitmap; unsigned int scale = QRCODE_SCALE, border = QRCODE_BORDER, level = QRCODE_LEVEL; @@ -237,7 +264,7 @@ int main(int argc, char **argv) { "Note that SERVER_NAME needs to be defined, for full features the client has\n" "to send referer information.\n"); return EXIT_FAILURE; - } + } /* check if we have https connection */ if (getenv("HTTPS") != NULL) @@ -273,16 +300,35 @@ int main(int argc, char **argv) { uri = uri_server_name; } + /* parse config file */ + if ((ini = iniparser_load(CONFIGFILE)) == NULL) { + fprintf(stderr, "cannot parse file " CONFIGFILE ", continue anyway\n"); + /* continue anyway, there is nothing essential in the config file */ + } else { + scale = get_ini_value(ini, 1, "general", "scale", scale, 1, QRCODE_MAX_SCALE); + border = get_ini_value(ini, 1, "general", "border", border, 0, QRCODE_MAX_BORDER); + level = get_ini_value(ini, 1, "general", "level", level, QR_ECLEVEL_L, QR_ECLEVEL_H); + overwrite = get_ini_value(ini, 0, "general", "allow overwrite", overwrite, 0, 1); + + scale = get_ini_value(ini, 1, server_name, "scale", scale, 1, QRCODE_MAX_SCALE); + border = get_ini_value(ini, 1, server_name, "border", border, 0, QRCODE_MAX_BORDER); + level = get_ini_value(ini, 1, server_name, "level", level, QR_ECLEVEL_L, QR_ECLEVEL_H); + overwrite = get_ini_value(ini, 0, server_name, "allow overwrite", overwrite, 0, 1); + + /* done reading config file, free */ + iniparser_freedict(ini); + } + /* get query string and read settings */ - if ((query_string = getenv("QUERY_STRING")) != NULL) { + if (overwrite && (query_string = getenv("QUERY_STRING")) != NULL) { /* do we have a special scale? */ - get_value(query_string, "scale", &scale, QRCODE_SCALE, 1, QRCODE_MAX_SCALE); + scale = get_query_value(query_string, "scale", scale, 1, QRCODE_MAX_SCALE); /* width of the border? */ - get_value(query_string, "border", &border, QRCODE_BORDER, 0, QRCODE_MAX_BORDER); + border = get_query_value(query_string, "border", border, 0, QRCODE_MAX_BORDER); /* error correction level? */ - get_value(query_string, "level", &level, QRCODE_LEVEL, 0, QR_ECLEVEL_H); + level = get_query_value(query_string, "level", level, QR_ECLEVEL_L, QR_ECLEVEL_H); } /* encode the QR-Code */ @@ -311,7 +357,6 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - /* free memory we no longer need */ if (uri_server_name) free(uri_server_name); diff --git a/cqrlogo.conf b/cqrlogo.conf new file mode 100644 index 0000000..1203971 --- /dev/null +++ b/cqrlogo.conf @@ -0,0 +1,16 @@ +# cqrlogo (CGI QR-Code logo) configuration file + +# We need a default section and call it 'general', so do not change this line. +[general] + +scale = 2 +border = 1 +level = 2 +allow overwrite = true + +# you may want to specify other settings for specific hosts +#[example.com] +#scale = 4 +#border = 2 +#level = 2 +#allow overwrite = false @@ -29,10 +29,16 @@ struct bitmap_t * bitmap_new(int width, int height); void bitmap_free(struct bitmap_t * bitmap); /*** encode_qrcode ***/ -struct bitmap_t * encode_qrcode (const char *text, unsigned int scale, unsigned int border, unsigned int level); +struct bitmap_t * encode_qrcode (const char *text, unsigned int scale, + unsigned int border, unsigned int level); -/*** get_value ***/ -int get_value(const char *query_string, const char *pattern, unsigned int *value, unsigned int def, unsigned int min, unsigned int max); +/*** get_query_value ***/ +unsigned int get_query_value(const char *query_string, const char *pattern, + unsigned int value, unsigned int min, unsigned int max); + +/*** get_ini_value ***/ +unsigned int get_ini_value(dictionary * ini, uint8_t type, const char * section, const char * parameter, + unsigned int value, unsigned int min, unsigned int max); #endif /* _CQRLOGO_H */ |