56#ifndef __BIT_TYPES_DEFINED__
57#define __BIT_TYPES_DEFINED__
67DB_ENV *db_env =
nullptr;
71TDB_CONTEXT *
db =
nullptr;
72typedef TDB_DATA DB_ENTRY;
75#error "Either Berkeley DB or Trivial DB must be available"
86 db_env->close(db_env, 0);
89 if (tdb_close(
db) != 0) {
104 if (S_ISDIR (st_buf.st_mode)) {
108 db_env_create(&db_env, 0);
109 if (db_env->open(db_env,
db_path, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK, 0666)) {
110 fprintf(stderr,
"FATAL: %s: Failed to open database environment in '%s'\n",
program_name,
db_path);
111 db_env->close(db_env, 0);
114 db_create(&
db, db_env, 0);
117 newPath.append(
"session", 7);
126 if (
db->open(
db,
nullptr,
"session",
nullptr, DB_BTREE, DB_CREATE, 0666)) {
127 fprintf(stderr,
"FATAL: %s: Failed to open db file '%s' in dir '%s'\n",
129 db_env->close(db_env, 0);
133 db_create(&
db,
nullptr, 0);
134 if (
db->open(
db,
nullptr,
db_path,
nullptr, DB_BTREE, DB_CREATE, 0666)) {
139#if _SQUID_FREEBSD_ && !defined(O_DSYNC)
141#define O_DSYNC O_SYNC
143 db = tdb_open(
db_path, 0, TDB_CLEAR_IF_FIRST, O_CREAT|O_DSYNC, 0666);
168 return (
db->get(
db,
nullptr, &key, data, 0) == 0);
171 *data = tdb_fetch(
db, key);
172 return (data->dptr !=
nullptr);
180 db->del(
db,
nullptr, &key, 0);
190 memcpy(dst, src->data, sz);
192 memcpy(dst, src->dptr, sz);
200 key.data =
const_cast<char*
>(details);
206 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(
const_cast<char*
>(details));
215 if (
dataSize(&data) !=
sizeof(timestamp)) {
216 fprintf(stderr,
"ERROR: %s: CORRUPTED DATABASE (%s)\n",
program_name, details);
220 copyValue(×tamp, &data,
sizeof(timestamp));
232 time_t now = time(
nullptr);
234 key.data =
static_cast<decltype(key.data)
>(details);
237 data.size =
sizeof(now);
238 db->put(
db,
nullptr, &key, &data, 0);
240 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(details);
242 data.dptr =
reinterpret_cast<decltype(data.dptr)
>(&now);
243 data.dsize =
sizeof(now);
244 tdb_store(
db, key, data, 0);
253 key.data =
static_cast<decltype(key.data)
>(details);
256 key.dptr =
reinterpret_cast<decltype(key.dptr)
>(details);
264 fprintf(stderr,
"Usage: %s [-t|-T session_timeout] [-b dbpath] [-a]\n",
program_name);
265 fprintf(stderr,
" -t sessiontimeout Idle timeout after which sessions will be forgotten (user activity will reset)\n");
266 fprintf(stderr,
" -T sessiontimeout Fixed timeout after which sessions will be forgotten (regardless of user activity)\n");
267 fprintf(stderr,
" -b dbpath Path where persistent session database will be kept\n");
268 fprintf(stderr,
" -a Active mode requiring LOGIN argument to start a session\n");
274 int default_action = 1;
278 while ((opt =
getopt(argc, argv,
"t:T:b:a?")) != -1) {
299 setbuf(stdout,
nullptr);
305 const char *channel_id = strtok(request,
" ");
306 char *detail = strtok(
nullptr,
"\n");
307 if (detail ==
nullptr) {
309 fprintf(stderr,
"FATAL: %s is concurrent and requires the concurrency option to be specified.\n",
program_name);
313 char *lastdetail = strrchr(detail,
' ');
314 size_t detail_len = strlen(detail);
316 if (strcmp(lastdetail,
" LOGIN") == 0) {
318 detail_len = (
size_t)(lastdetail-detail);
320 }
else if (strcmp(lastdetail,
" LOGOUT") == 0) {
322 detail_len = (
size_t)(lastdetail-detail);
324 }
else if (!default_action && strcmp(lastdetail,
" -") == 0) {
327 detail_len = (
size_t)(lastdetail-detail);
333 printf(
"%s OK message=\"Bye\"\n", channel_id);
334 }
else if (action == 1) {
336 printf(
"%s OK message=\"Welcome\"\n", channel_id);
341 printf(
"%s OK\n", channel_id);
342 }
else if (default_action == 1) {
344 printf(
"%s ERR message=\"Welcome\"\n", channel_id);
346 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()
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)