57#ifndef __BIT_TYPES_DEFINED__
58#define __BIT_TYPES_DEFINED__
68DB_ENV *db_env =
nullptr;
72TDB_CONTEXT *
db =
nullptr;
73typedef TDB_DATA DB_ENTRY;
76#error "Either Berkeley DB or Trivial DB must be available"
87 db_env->close(db_env, 0);
90 if (tdb_close(
db) != 0) {
105 if (S_ISDIR (st_buf.st_mode)) {
109 db_env_create(&db_env, 0);
110 if (db_env->open(db_env,
db_path, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK, 0666)) {
111 fprintf(stderr,
"FATAL: %s: Failed to open database environment in '%s'\n",
program_name,
db_path);
112 db_env->close(db_env, 0);
115 db_create(&
db, db_env, 0);
118 newPath.append(
"session", 7);
127 if (
db->open(
db,
nullptr,
"session",
nullptr, DB_BTREE, DB_CREATE, 0666)) {
128 fprintf(stderr,
"FATAL: %s: Failed to open db file '%s' in dir '%s'\n",
130 db_env->close(db_env, 0);
134 db_create(&
db,
nullptr, 0);
135 if (
db->open(
db,
nullptr,
db_path,
nullptr, DB_BTREE, DB_CREATE, 0666)) {
140#if _SQUID_FREEBSD_ && !defined(O_DSYNC)
142#define O_DSYNC O_SYNC
144 db = tdb_open(
db_path, 0, TDB_CLEAR_IF_FIRST, O_CREAT|O_DSYNC, 0666);
169 return (
db->get(
db,
nullptr, &key, data, 0) == 0);
172 *data = tdb_fetch(
db, key);
173 return (data->dptr !=
nullptr);
181 db->del(
db,
nullptr, &key, 0);
191 memcpy(dst, src->data, sz);
193 memcpy(dst, src->dptr, sz);
201 key.data =
const_cast<char*
>(details);
207 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(
const_cast<char*
>(details));
216 if (
dataSize(&data) !=
sizeof(timestamp)) {
217 fprintf(stderr,
"ERROR: %s: CORRUPTED DATABASE (%s)\n",
program_name, details);
221 copyValue(×tamp, &data,
sizeof(timestamp));
233 time_t
now = time(
nullptr);
235 key.data =
static_cast<decltype(key.data)
>(details);
238 data.size =
sizeof(
now);
239 db->put(
db,
nullptr, &key, &data, 0);
241 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(details);
243 data.dptr =
reinterpret_cast<decltype(data.dptr)
>(&
now);
244 data.dsize =
sizeof(
now);
245 tdb_store(
db, key, data, 0);
254 key.data =
static_cast<decltype(key.data)
>(details);
257 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(details);
265 fprintf(stderr,
"Usage: %s [-t|-T session_timeout] [-b dbpath] [-a]\n",
program_name);
266 fprintf(stderr,
" -t sessiontimeout Idle timeout after which sessions will be forgotten (user activity will reset)\n");
267 fprintf(stderr,
" -T sessiontimeout Fixed timeout after which sessions will be forgotten (regardless of user activity)\n");
268 fprintf(stderr,
" -b dbpath Path where persistent session database will be kept\n");
269 fprintf(stderr,
" -a Active mode requiring LOGIN argument to start a session\n");
275 int default_action = 1;
279 while ((opt =
getopt(argc, argv,
"t:T:b:a?")) != -1) {
300 setbuf(stdout,
nullptr);
306 const char *channel_id = strtok(request,
" ");
307 char *detail = strtok(
nullptr,
"\n");
308 if (detail ==
nullptr) {
310 fprintf(stderr,
"FATAL: %s is concurrent and requires the concurrency option to be specified.\n",
program_name);
314 char *lastdetail = strrchr(detail,
' ');
315 size_t detail_len = strlen(detail);
317 if (strcmp(lastdetail,
" LOGIN") == 0) {
319 detail_len = (
size_t)(lastdetail-detail);
321 }
else if (strcmp(lastdetail,
" LOGOUT") == 0) {
323 detail_len = (
size_t)(lastdetail-detail);
325 }
else if (!default_action && strcmp(lastdetail,
" -") == 0) {
328 detail_len = (
size_t)(lastdetail-detail);
334 printf(
"%s OK message=\"Bye\"\n", channel_id);
337 printf(
"%s OK message=\"Welcome\"\n", channel_id);
342 printf(
"%s OK\n", channel_id);
343 }
else if (default_action == 1) {
345 printf(
"%s ERR message=\"Welcome\"\n", channel_id);
347 printf(
"%s ERR message=\"No session available\"\n", channel_id);
#define HELPER_INPUT_BUFFER
static bool fetchKey(DB_ENTRY &key, DB_ENTRY *data)
static void shutdown_db()
int main(int argc, char **argv)
static void session_login(char *details, size_t len)
static void init_db(void)
static void session_logout(char *details, size_t len)
static void copyValue(void *dst, const DB_ENTRY *src, size_t sz)
static int session_active(const char *details, size_t len)
static size_t dataSize(DB_ENTRY *data)
static void deleteEntry(DB_ENTRY &key)
const char * program_name
int getopt(int nargc, char *const *nargv, const char *ostr)
static bool action(int fd, size_t metasize, const char *fn, const char *url, const SquidMetaList &meta)