addpiwik.c

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

// ------------------------------------------------------------------------
char	*__author__ = "Markus Stumpf <mailto:srv-src-extfilter-piwik@maexotic.de>";
char	*__source__ = "http://software.maexotic.de/piwik/addpiwik/";
char	*__version__ = "1.1";
char	*__license__ = "Copyright (c) 2011 Markus Stumpf. All rights reserved.\
See http://software.maexotic.de/license/license.txt for\
the full text of the license.";

// ------------------------------------------------------------------------
// HTML code snippet for errors
// ------------------------------------------------------------------------
char	*ERROR_NOENV = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\
  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n\
<head>\n\
  <title>Error: '%s' not set</title>\n\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n\
  <meta http-equiv=\"Content-Language\" content=\"en\" />\n\
  <meta name=\"generator\" content=\"%s\" />\n\
  <meta name=\"author\" content=\"%s\" />\n\
</head>\n\
<body>\n\
  <h1>Error: '%s' not set</h1>\n\
  <p>%s - version: %s</p>\n\
  <p>Environment variable '%s' not set.</p>\n\
</body>\n\
</html>\n";

// ------------------------------------------------------------------------
// this is the PIWIK tracker Javascript code snippet
// ------------------------------------------------------------------------
char	*PIWIK_TRACKER = "<!-- Piwik Tag -->\n\
<script type=\"text/javascript\">\n\
var pkBaseURL = ((\"https:\" == document.location.protocol) ? \"https://%s\" : \"http://%s\");\n\
document.write(unescape(\"%%3Cscript src='\" + pkBaseURL + \"piwik.js' type='text/javascript'%%3E%%3C/script%%3E\"));\n\
</script>\n\
<script type=\"text/javascript\">\n\
try {\n\
var piwikTracker = Piwik.getTracker(pkBaseURL + \"piwik.php\", %s);\n\
piwikTracker.trackPageView();\n\
piwikTracker.enableLinkTracking();\n\
} catch( err ) {}\n\
</script>\n\
<!-- End Piwik Tag -->\n";

// ------------------------------------------------------------------------
void exit_error(char *m, char *p)
{
    printf(ERROR_NOENV, m, p, __source__, m, p, __version__, m);
    fflush(stdout);
    exit(1);
}

// ------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    char	*piwik_url;
    char	*piwik_idsite;
    char	*line = NULL;
    size_t	len = 0;
    ssize_t	read;
    regex_t	preg;
    regmatch_t	match[1];

    if (NULL == (piwik_url = getenv("PIWIK_URL")))
	exit_error("PIWIK_URL", argv[0]);

    if (NULL == (piwik_idsite = getenv("PIWIK_IDSITE")))
	exit_error("PIWIK_IDSITE", argv[0]);

    if (0 != regcomp(&preg, "</body>", REG_ICASE)) {
	// should never happen
        printf("%s: regex compile failed", argv[0]);
	exit(1);
    }


    while ((read = getline(&line, &len, stdin)) != -1) {
	if (0 == regexec(&preg, line, 1, match, 0)) {

	    char 	*rm;
	    rm = line + match[0].rm_so;

	    // put a '\0' instead of '<' and write the line
	    *rm = '\0'; printf("%s\n", line);

	    printf(PIWIK_TRACKER, piwik_url, piwik_url, piwik_idsite);

	    // restore the '<' and print rest of line
	    *rm = '<'; printf("%s", rm);
	    
	} else
            printf("%s", line);
    }

    fflush(stdout);

    // not really needed as we exit anyway
    if (line) free(line);

    exit(0);
}