diff -r -u -N trunk/configure.ac trunk-time_quota/configure.ac
--- trunk/configure.ac	2011-04-04 21:08:49.000000000 +0200
+++ trunk-time_quota/configure.ac	2011-04-04 21:23:41.000000000 +0200
@@ -3434,6 +3434,7 @@
 	helpers/external_acl/session/Makefile \
 	helpers/external_acl/unix_group/Makefile \
 	helpers/external_acl/wbinfo_group/Makefile \
+	helpers/external_acl/time_quota/Makefile \
 	helpers/log_daemon/Makefile \
 	helpers/log_daemon/DB/Makefile \
 	helpers/log_daemon/file/Makefile \
diff -r -u -N trunk/configure.ac.orig trunk-time_quota/configure.ac.orig
--- trunk/helpers/external_acl/Makefile.am	2011-03-19 17:23:31.000000000 +0100
+++ trunk-time_quota/helpers/external_acl/Makefile.am	2011-04-04 21:23:41.000000000 +0200
@@ -7,6 +7,7 @@
 	LM_group \
 	session \
 	unix_group \
-	wbinfo_group
+	wbinfo_group \
+	time_quota
 
 SUBDIRS=$(EXTERNAL_ACL_HELPERS)
diff -r -u -N trunk/helpers/external_acl/time_quota/config.test trunk-time_quota/helpers/external_acl/time_quota/config.test
--- trunk/helpers/external_acl/time_quota/config.test	1970-01-01 01:00:00.000000000 +0100
+++ trunk-time_quota/helpers/external_acl/time_quota/config.test	2011-03-19 17:25:01.000000000 +0100
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Actual intended test
+if [ -f /usr/include/db_185.h ]; then
+    exit 0
+fi
+if [ -f /usr/include/db.h ] && grep dbopen /usr/include/db.h; then
+    exit 0
+fi
+exit 1
diff -r -u -N trunk/helpers/external_acl/time_quota/ext_time_quota_acl.8 trunk-time_quota/helpers/external_acl/time_quota/ext_time_quota_acl.8
--- trunk/helpers/external_acl/time_quota/ext_time_quota_acl.8	1970-01-01 01:00:00.000000000 +0100
+++ trunk-time_quota/helpers/external_acl/time_quota/ext_time_quota_acl.8	2011-04-04 21:20:28.000000000 +0200
@@ -0,0 +1,274 @@
+.if !'po4a'hide' .TH ext_time_quota_acl 8 "22 March 2011"
+.
+.SH NAME
+.if !'po4a'hide' .B ext_time_quota_acl
+.if !'po4a'hide' \-
+Squid time quota external acl helper.
+.PP
+Version 1.0
+.
+.SH SYNOPSIS
+.if !'po4a'hide' .B ext_time_quota_acl
+.if !'po4a'hide' .B "[\-b database] [\-l logfile] configfile
+.
+.SH DESCRIPTION
+.B ext_time_quota_acl
+allows an administrator to define time budgets for the users of squid
+to limit the time using squid.
+.PP
+The primary use is for parental control for children. The parents can
+define a time budget (e.g. 1 hour per day) which is enforced through
+this helper.
+.
+.SH OPTIONS
+.
+.if !'po4a'hide' .TP
+.if !'po4a'hide' .B "\-b database"
+.B Filename
+of persistent database. If not specified the available and used time
+budgets will be kept in memory only and will reset each time Squid
+restarts it's helpers (Squid restart or rotation of logs).
+.
+.if !'po4a'hide' .TP
+.if !'po4a'hide' .B "\-l logfile"
+.B Filename
+to a log file where all logging and debugging information will be
+written.
+.
+.if !'po4a'hide' .TP
+.if !'po4a'hide' .B configfile
+This file contains the definition of the time budgets for the users.
+.PP
+.
+.SH USER AUTHENTICATION
+.PP
+This helper needs to know the identity of the user to associate a time
+budget with this user. Currently only proxy_auth is able to deliver
+this information. The following paragraph gives a short overview of a
+very basic setup using "basic_ncsa_auth". More different options and a
+complete and detailed explanation can be found in the Squid user
+manual.
+.PP
+Start by setting up a file containing usernames and the corresponding
+passwords. Use the htpasswd program coming with Apache to enter the
+data and repeat this step for all users.
+.PP
+.if !'po4a'hide' .RS
+root# 
+.if !'po4a'hide' .B htpasswd /etc/squid/passwd john
+.if !'po4a'hide' .br
+New password: 
+.if !'po4a'hide' .B johnssecret
+.if !'po4a'hide' .br
+Re-type new password: 
+.if !'po4a'hide' .B johnssecret
+.if !'po4a'hide' .br
+Adding password for user john
+.if !'po4a'hide' .RE
+.PP
+Edit squid.conf to define a basic authentication program called
+"basic_ncsa_auth", which authenticates users with the above password
+file. Define a ACL using that program and deny access to web pages for
+unautenticated users.
+.PP
+.if !'po4a'hide' .RS
+#
+.if !'po4a'hide' .br
+# Define program and password file for auth.
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B auth_param basic program /usr/libexec/basic_ncsa_auth /etc/squid/passwd
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+# Define ACL
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B acl authenticated_users proxy_auth REQUIRED
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+# Deny access for unauthenticated users
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B http_access deny !authenticated_users
+.if !'po4a'hide' .br
+.if !'po4a'hide' .RE
+.PP
+After restarting Squid it should allow access only for authenticated
+users with the configured names and passwords. All other users will be
+rejected.
+.
+.SH DEFINING TIME QUOTAS
+.PP
+The time quotas of the users are defined in a text file typically
+residing in /etc/squid/time_quota. Any line starting with "#" contains
+a comment and is ignored. Every line must start with a username
+followed by a time budget and a corresponding time period separated by
+"/". Here is an example file:
+.PP
+.if !'po4a'hide' .RS
+# username budget / period
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B john 8h / 1d
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B littlejoe 1h / 1d
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B babymary 30m / 1w
+.if !'po4a'hide' .br
+.if !'po4a'hide' .RE
+.PP
+John has a time budget of 8 hours every day, littlejoe is only allowed
+1 hour and the poor babymary only 30 minutes a week.
+.PP
+You can use "s" for seconds, "m" for minutes, "h" for hours, "d" for
+days and "w" for weeks. Numerical values can be given as integer
+values or with a fraction. E.g. "0.5h" means 30 minutes.
+.
+.SH CONFIGURATION
+.PP
+This helper is also configured in squid.conf where you first declare the helper, then define a ACL which then decides when to allow or deny. Enter the following text 
+.if !'po4a'hide' .B after
+the user authentication.
+.PP
+.if !'po4a'hide' .RS
+#
+.if !'po4a'hide' .br
+# Define program and quota file
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B external_acl_type time_quota ttl=60 children-max=1 %LOGIN /usr/libexec/ext_time_quota_acl -b /var/run/squid/time_quota.db /etc/squid/time_quota
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+# Define ACL for time_quota helper
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B acl time_quota external time_quota
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+# Deny access if quota exceeded
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B http_access deny !time_quota
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+# If quota exceeds, tell user
+.if !'po4a'hide' .br
+#
+.if !'po4a'hide' .br
+.if !'po4a'hide' .B deny_info TIME_QUOTA_EXCEEDED time_quota
+.if !'po4a'hide' .RE
+.PP
+After restarting Squid it should allow access only for authenticated
+users as long as they have time budget left. If the buget is exceeded
+or an invalid username or password is given, the user will be prompted
+for a correct username and password having time quota left.
+.PP
+For Unix machines it should be possible for the parents to
+authenticate using ident so that they always have access to the
+internet even without supplying user names and passwords. If this
+"falls through", then the above helper would be called. This could be
+done by something like "http_access allow ident" with a correct ident
+configuration. This is out of scope of this manual page.
+.
+.SH LOGGING
+.
+Whenever you hit a problem, then start the helper with
+.if !'po4a'hide' .B -l logfile
+(e.g. "-l /tmp/time_quota.log") and look into that log file to find
+any problem.
+.
+.SH LIMITATIONS
+This helper only controls access to the internet through HTTP. It does
+not control other protocols, like VOIP, ICQ, IRC, FTP, IMAP, SMTP or
+SSH.
+.PP
+Desktop browsers are typically able to deal with HTTP proxies like
+squid. But more and more different programs and devices (smartphones,
+games on mobile devices, ...) are using the internet over HTTP. These
+devices are often not able to work through an authenticating proxy.
+Sometimes one can sucessfully use the internet browser on those devices
+but often online games and other stuff fails.
+.PP
+A more general control to internet access could be a captive portal
+(like pfSense or ChilliSpot) or maybe a 802.11X solution. But the
+latter is often not supported by mobile devices.
+.
+.SH IMPLEMENTATION
+The helper is called once a minute and asked if the current user is
+allowed to access squid. The helper will reduce the remaining time
+budget of this user and return "OK" if there is budget left. Otherwise
+it will return "ERR".
+.PP
+If the configured time period (e.g. "1w" for babymary) is over, the
+time budget will be restored to the configured value thus allowing the
+user to access squid with a fresh budget.
+.PP
+If the time between the current request and the previous request is
+greater than 5 minutes, the current request will be considered as a
+new request and the time budget will not be decreased. If the time is
+less than 5 minutes, than both request will be considered as part of
+the same active time period and the time budget will be decreased by
+the time difference. This allows the user to make arbitrary breaks
+during internet access without decreasing the time budget.
+.
+.SH FURTHER IDEAS
+The following ideas could further improve this helper. Maybe someone
+wants to help? Any support or feedback is welcome!
+.if !'po4a'hide' .TP
+There should be a way for a user to see its configured and remaining
+time budget. This could be realized by implementing a web page
+accessing the database of the helper showing the corresponding
+data. One of the problems to be solved is user authentication.
+.if !'po4a'hide' .TP
+We could always return "OK" and use the module simply as an internet
+usage tracker showing who has staid how long in the WWW.
+.PP
+.
+.SH AUTHOR
+This program and documentation was written by
+.if !'po4a'hide' .I Dr. Tilmann Bubeck <t.bubeck@reinform.de>
+.
+.SH COPYRIGHT
+This program and documentation is copyright to the authors named above.
+.PP
+Distributed under the GNU General Public License (GNU GPL) version 2 or later (GPLv2+).
+.
+.SH QUESTIONS
+Questions on the usage of this program can be sent to the
+.I Squid Users mailing list
+.if !'po4a'hide' <squid-users@squid-cache.org>
+.
+.SH REPORTING BUGS
+Bug reports need to be made in English.
+See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report.
+.PP
+Report bugs or bug fixes using http://bugs.squid-cache.org/
+.PP
+Report serious security bugs to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+.PP
+Report ideas for new improvements to the
+.I Squid Developers mailing list
+.if !'po4a'hide' <squid-dev@squid-cache.org>
+.
+.SH SEE ALSO
+.if !'po4a'hide' .BR squid "(8), "
+.if !'po4a'hide' .BR basic_ncsa_auth "(8), "
+.if !'po4a'hide' .BR GPL "(7), "
+.br
+The Squid FAQ wiki
+.if !'po4a'hide' http://wiki.squid-cache.org/SquidFaq
+.br
+The Squid Configuration Manual
+.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
diff -r -u -N trunk/helpers/external_acl/time_quota/ext_time_quota_acl.cc trunk-time_quota/helpers/external_acl/time_quota/ext_time_quota_acl.cc
--- trunk/helpers/external_acl/time_quota/ext_time_quota_acl.cc	1970-01-01 01:00:00.000000000 +0100
+++ trunk-time_quota/helpers/external_acl/time_quota/ext_time_quota_acl.cc	2011-04-04 21:19:49.000000000 +0200
@@ -0,0 +1,398 @@
+/*
+ * ext_time_quota_acl: Squid external acl helper for quota on usage.
+ *
+ * Copyright (C) 2011 Dr. Tilmann Bubeck <t.bubeck@reinform.de>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "helpers/defines.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+/* At this point all Bit Types are already defined, so we must
+   protect from multiple type definition on platform where
+   __BIT_TYPES_DEFINED__ is not defined.
+ */
+#ifndef        __BIT_TYPES_DEFINED__
+#define        __BIT_TYPES_DEFINED__
+#endif
+
+#if HAVE_DB_185_H
+#include <db_185.h>
+#elif HAVE_DB_H
+#include <db.h>
+#endif
+
+char *db_path = NULL;
+const char *program_name;
+
+DB *db = NULL;
+
+#define KEY_LAST_ACTIVITY            "last-activity"
+#define KEY_PERIOD_START             "period-start"
+#define KEY_PERIOD_LENGTH_CONFIGURED "period-length-configured"
+#define KEY_TIME_BUDGET_LEFT         "time-budget-left"
+#define KEY_TIME_BUDGET_CONFIGURED   "time-budget-configured"
+
+/** If there is more than this given number of seconds between two
+ * sucessive requests, than the second request will be treated as a 
+ * new request and the time between first and seconds request will
+ * be treated as a activity pause.
+ *
+ * Otherwise the following request will be treated as belonging to the
+ * same activity and the quota will be reduced.
+ */
+static int pauseLength = 300;
+
+static FILE *logfile = stderr;
+
+static void open_log(const char *logfilename) {
+    logfile = fopen(logfilename, "a");
+    if ( logfile == NULL ) {
+	perror(logfilename);
+	logfile = stderr;
+    }
+}
+
+static void log(const char *format, ...)
+{
+    va_list args;
+    time_t now = time(NULL);
+
+    fprintf(logfile, "%ld: ", now);
+    va_start (args, format);
+    vfprintf (logfile, format, args);
+    va_end (args);
+    fflush(logfile);
+}
+
+static void init_db(void)
+{
+    log("opening time quota database \"%s\".\n", db_path);
+    db = dbopen(db_path, O_CREAT | O_RDWR, 0666, DB_BTREE, NULL);
+    if (!db) {
+        log("FATAL: %s: Failed to open time_quota db '%s'\n", program_name, db_path);
+        fprintf(stderr, "FATAL: %s: Failed to open time_quota db '%s'\n", program_name, db_path);
+        exit(1);
+    }
+}
+
+static void shutdown_db(void)
+{
+    db->close(db);
+}
+
+int session_is_active = 0;
+
+static void writeTime(const char *user_key, const char *sub_key, time_t t)
+{
+    char keybuffer[1024];
+    DBT key, data;
+
+    if ( strlen(user_key) + strlen(sub_key) + 1 + 1 > sizeof(keybuffer) ) {
+	fprintf(stderr, "ERROR: %s: key too long (%s,%s)\n", 
+		program_name, user_key, sub_key);
+    } else {
+	snprintf(keybuffer, sizeof(keybuffer), "%s-%s", user_key, sub_key);
+
+	key.data = (void *)keybuffer;
+	key.size = strlen(keybuffer);
+	data.data = &t;
+	data.size = sizeof(t);
+	db->put(db, &key, &data, 0);
+	log("writeTime(\"%s\", %d)\n", keybuffer, t);
+    }
+}
+
+static time_t readTime(const char *user_key, const char *sub_key)
+{
+    char keybuffer[1024];
+    DBT key, data;
+    time_t t = 0;
+
+    if ( strlen(user_key) + 1 + strlen(sub_key) + 1 > sizeof(keybuffer) ) {
+	fprintf(stderr, "ERROR: %s: key too long (%s,%s)\n", 
+		program_name, user_key, sub_key);
+    } else {
+	snprintf(keybuffer, sizeof(keybuffer), "%s-%s", user_key, sub_key);
+
+	key.data = (void *)keybuffer;
+	key.size = strlen(keybuffer);
+	if (db->get(db, &key, &data, 0) == 0) {
+	    if (data.size != sizeof(t)) {
+		fprintf(stderr, "ERROR: %s: CORRUPTED DATABASE (%s)\n", program_name, keybuffer);
+	    } else {
+		memcpy(&t, data.data, sizeof(t));
+	    }
+	}
+	log("readTime(\"%s\")=%d\n", keybuffer, t);
+    }
+
+    return t;
+}
+
+static void parseTime(const char *s, time_t *secs, time_t *start)
+{
+    double value;
+    char unit;
+    struct tm *ltime;
+    int periodLength = 3600;
+
+    *secs = 0;
+    *start = time(NULL);
+    ltime = localtime(start);
+
+    sscanf(s, " %lf %c", &value, &unit);
+    switch (unit) {
+    case 's':
+	periodLength = 1;
+	break;
+    case 'm':
+	periodLength = 60;
+	*start -= ltime->tm_sec;
+	break;
+    case 'h':
+	periodLength = 3600;
+	*start -= ltime->tm_min * 60 + ltime->tm_sec;
+	break;
+    case 'd':
+	periodLength = 24 * 3600;
+	*start -= ltime->tm_hour * 3600 + ltime->tm_min * 60 + ltime->tm_sec;
+	break;
+    case 'w':
+	periodLength = 7 * 24 * 3600;
+	*start -= ltime->tm_hour * 3600 + ltime->tm_min * 60 + ltime->tm_sec;
+	*start -= ltime->tm_wday * 24 * 3600;
+	*start += 24 * 3600;         // in europe, the week starts monday
+	break;
+    default:
+	log("Wrong time unit \"%c\". Only \"m\", \"h\", \"d\", or \"w\" allowed.\n");
+	break;
+    }
+
+    *secs = (long)(periodLength * value);
+}
+
+
+/** This function parses the time quota file and stores it
+ * in memory.
+ */
+static void readConfig(const char *filename) 
+{
+    char line[1024];          /* the buffer for the lines read
+				   from the dict file */
+    char *cp;			/* a char pointer used to parse
+				   each line */
+    char *username;		/* for the username */
+    char *budget;
+    char *period;
+    FILE *FH;
+    time_t t;
+    time_t budgetSecs, periodSecs;
+    time_t start;
+
+    log("reading config file \"%s\".\n", filename);
+
+    FH = fopen(filename, "r");
+    if ( FH ) {
+	/* the pointer to the first entry in the linked list */
+	while ((cp = fgets (line, sizeof(line), FH)) != NULL) {
+	    if (line[0] == '#') {
+		continue;
+	    }
+	    if ((cp = strchr (line, '\n')) != NULL) {
+		/* chop \n characters */
+		*cp = '\0';
+	    }
+	    log("read config line \"%s\".\n", line);
+	    if ((cp = strtok (line, "\t ")) != NULL) {
+		username = cp;
+		
+		/* get the time budget */
+		budget = strtok (NULL, "/");
+		period = strtok (NULL, "/");
+
+		parseTime(budget, &budgetSecs, &start);
+		parseTime(period, &periodSecs, &start);
+
+		log("user \"%s\": %lds / %lds starting %lds\n", 
+		    username, budgetSecs, periodSecs, start);
+
+		writeTime(username, KEY_PERIOD_START, start);
+		writeTime(username, KEY_PERIOD_LENGTH_CONFIGURED, periodSecs);
+		writeTime(username, KEY_TIME_BUDGET_CONFIGURED, budgetSecs);
+		t = readTime(username, KEY_TIME_BUDGET_CONFIGURED);
+		writeTime(username, KEY_TIME_BUDGET_LEFT, t);
+	    }
+	}
+	fclose(FH);
+    } else {
+	perror(filename);
+    }
+}
+
+static void processActivity(const char *user_key)
+{
+     time_t now = time(NULL);
+     time_t lastActivity;
+     time_t activityLength;
+     time_t periodStart;
+     time_t periodLength;
+     time_t userPeriodLength;
+     time_t timeBudgetCurrent;
+     time_t timeBudgetConfigured;
+
+     log("processActivity(\"%s\")\n", user_key);
+
+     // [1] Reset period if over
+     periodStart = readTime(user_key, KEY_PERIOD_START);
+     if ( periodStart == 0 ) {
+	 // This is the first period ever.
+	 periodStart = now;
+	 writeTime(user_key, KEY_PERIOD_START, periodStart);
+     }
+
+     periodLength = now - periodStart;
+     userPeriodLength = readTime(user_key, KEY_PERIOD_LENGTH_CONFIGURED);
+     if ( userPeriodLength == 0 ) {
+	 // This user is not configured. Allow anything.
+	 log("No period length found for user \"%s\". Quota for this user disabled.\n", user_key);
+	 writeTime(user_key, KEY_TIME_BUDGET_LEFT, pauseLength);
+     } else {
+	 if ( periodLength >= userPeriodLength ) {
+	     // a new period has started.
+	     log("New time period started for user \"%s\".\n", user_key);
+	     while ( periodStart < now ) {
+		 periodStart += periodLength;
+	     }
+	     writeTime(user_key, KEY_PERIOD_START, periodStart);
+	     timeBudgetConfigured = readTime(user_key, KEY_TIME_BUDGET_CONFIGURED);
+	     if ( timeBudgetConfigured == 0 ) {
+		 log("No time budget configured for user \"%s\". Quota for this user disabled.\n", user_key);
+		 writeTime(user_key, KEY_TIME_BUDGET_LEFT, pauseLength);
+	     } else {
+		 writeTime(user_key, KEY_TIME_BUDGET_LEFT, timeBudgetConfigured);
+	     }
+	 }
+     }
+
+     // [2] Decrease time budget iff activity
+     lastActivity = readTime(user_key, KEY_LAST_ACTIVITY);
+     if ( lastActivity == 0 ) {
+	 // This is the first request ever
+	 writeTime(user_key, KEY_LAST_ACTIVITY, now);
+     } else {
+	 activityLength = now - lastActivity;
+	 if ( activityLength >= pauseLength ) {
+	     // This is an activity pause.
+	     log("Activity pause detected for user \"%s\".\n", user_key);
+	     writeTime(user_key, KEY_LAST_ACTIVITY, now);
+	 } else {
+	     // This is real usage.
+	     writeTime(user_key, KEY_LAST_ACTIVITY, now);
+
+	     log("Time budget reduced by %ld for user \"%s\".\n", 
+		 activityLength, user_key);
+	     timeBudgetCurrent = readTime(user_key, KEY_TIME_BUDGET_LEFT);
+	     timeBudgetCurrent -= activityLength;
+	     writeTime(user_key, KEY_TIME_BUDGET_LEFT, timeBudgetCurrent);
+	 }
+     }
+
+     timeBudgetCurrent = readTime(user_key, KEY_TIME_BUDGET_LEFT);
+     if ( timeBudgetCurrent > 0 ) {
+	 log("OK for user \"%s\".\n", user_key);
+	 SEND_OK("");
+     } else {
+	 log("ERR for user \"%s\".\n", user_key);
+	 SEND_ERR("Time budget exceeded.");
+     }
+
+     db->sync(db, 0);
+}
+
+static void usage(void)
+{
+    log("Wrong usage. Please reconfigure in squid.conf.\n");
+
+    fprintf(stderr, "Usage: %s [-l logfile] [-b dbpath]\n", program_name);
+    fprintf(stderr, "	-l logfile	log messages to logfile\n");
+    fprintf(stderr, "	-b dbpath		Path where persistent session database will be kept\n");
+}
+
+int main(int argc, char **argv)
+{
+    char request[HELPER_INPUT_BUFFER];
+    int opt;
+
+    program_name = argv[0];
+
+    while ((opt = getopt(argc, argv, "l:b:h?")) != -1) {
+        switch (opt) {
+        case 'l':
+	    open_log(optarg);
+            break;
+        case 'b':
+            db_path = optarg;
+            break;
+        case 'h':
+        case '?':
+            usage();
+            exit(0);
+            break;
+        }
+    }
+
+    log("Starting %s\n", __FILE__);
+    setbuf(stdout, NULL);
+
+    init_db();
+
+    if ( optind + 1 != argc ) {
+	usage();
+	exit(1);
+    } else {
+	readConfig(argv[optind]);
+    }
+
+    log("Waiting for requests...\n");
+    while (fgets(request, HELPER_INPUT_BUFFER, stdin)) {
+	// we expect the following line syntax: "%LOGIN 
+        const char *user_key = NULL;
+        user_key = strtok(request, " \n");
+
+	processActivity(user_key);
+    }
+    log("Ending %s\n", __FILE__);
+    shutdown_db();
+    return 0;
+}
diff -r -u -N trunk/helpers/external_acl/time_quota/Makefile.am trunk-time_quota/helpers/external_acl/time_quota/Makefile.am
--- trunk/helpers/external_acl/time_quota/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ trunk-time_quota/helpers/external_acl/time_quota/Makefile.am	2011-03-19 17:29:11.000000000 +0100
@@ -0,0 +1,10 @@
+include $(top_srcdir)/src/Common.am
+
+libexec_PROGRAMS 		= ext_time_quota_acl
+man_MANS 			= ext_time_quota_acl.8
+EXTRA_DIST			= ext_time_quota_acl.8 config.test
+ext_time_quota_acl_SOURCES	= ext_time_quota_acl.cc
+
+LDADD = \
+	$(COMPAT_LIB) \
+	$(LIB_DB)
