unrealircd/src/api-history-backend.c

198 lines
4.6 KiB
C
Raw Normal View History

2020-03-29 02:16:53 -07:00
/************************************************************************
* UnrealIRCd - Unreal Internet Relay Chat Daemon - src/api-history-backend.c
* (c) 2019- Bram Matthys and The UnrealIRCd team
*
* See file AUTHORS in IRC package for additional names of
* the programmers.
*
* 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "unrealircd.h"
MODVAR HistoryBackend *historybackends = NULL; /**< List of registered history backends */
void history_backend_init(void)
{
}
/**
* Returns a history backend based on the given token name.
*
* @param name The name of the history backend.
* @return Returns the handle to the history backend,
* or NULL if not found.
*/
HistoryBackend *HistoryBackendFind(const char *name)
{
HistoryBackend *m;
for (m = historybackends; m; m = m->next)
{
if (!strcasecmp(name, m->name))
return m;
}
return NULL;
}
/**
* Adds a new history backend.
*
* @param module The module which provides this history backend.
* @param mreq The details of the request such as token name, access check handler, etc.
* @return Returns the handle to the new token if successful, otherwise NULL.
* The module's error code contains specific information about the
* error.
*/
HistoryBackend *HistoryBackendAdd(Module *module, HistoryBackendInfo *mreq)
{
HistoryBackend *m;
int exists = 0;
if (!mreq->history_add || !mreq->history_request ||
!mreq->history_destroy || !mreq->history_set_limit)
{
if (module)
module->errorcode = MODERR_INVALID;
ircd_log(LOG_ERROR, "HistoryBackendAdd(): missing a handler for add/del/request/destroy/set_limit");
return NULL;
}
m = HistoryBackendFind(mreq->name);
if (m)
{
exists = 1;
if (m->unloaded)
{
m->unloaded = 0;
} else {
if (module)
module->errorcode = MODERR_EXISTS;
return NULL;
}
} else {
/* New history backend */
m = safe_alloc(sizeof(HistoryBackend));
safe_strdup(m->name, mreq->name);
}
/* Add or update the following fields: */
m->owner = module;
m->history_add = mreq->history_add;
m->history_request = mreq->history_request;
m->history_destroy = mreq->history_destroy;
m->history_set_limit = mreq->history_set_limit;
if (!exists)
AddListItem(m, historybackends);
if (module)
{
ModuleObject *mobj = safe_alloc(sizeof(ModuleObject));
mobj->type = MOBJ_HISTORY_BACKEND;
mobj->object.history_backend = m;
AddListItem(mobj, module->objects);
module->errorcode = MODERR_NOERROR;
}
return m;
}
void unload_history_backend_commit(HistoryBackend *m)
{
/* Destroy the object */
DelListItem(m, historybackends);
safe_free(m->name);
safe_free(m);
}
/**
* Removes the specified history backend.
*
* @param m The history backend to remove.
*/
void HistoryBackendDel(HistoryBackend *m)
{
if (m->owner)
{
ModuleObject *mobj;
for (mobj = m->owner->objects; mobj; mobj = mobj->next) {
if (mobj->type == MOBJ_HISTORY_BACKEND && mobj->object.history_backend == m)
{
DelListItem(mobj, m->owner->objects);
safe_free(mobj);
break;
}
}
m->owner = NULL;
}
if (loop.ircd_rehashing)
m->unloaded = 1;
else
unload_history_backend_commit(m);
}
void unload_all_unused_history_backends(void)
{
HistoryBackend *m, *m_next;
for (m = historybackends; m; m = m_next)
{
m_next = m->next;
if (m->unloaded)
unload_history_backend_commit(m);
}
}
int history_add(char *object, MessageTag *mtags, char *line)
{
HistoryBackend *hb;
for (hb = historybackends; hb; hb=hb->next)
hb->history_add(object, mtags, line);
return 1;
}
int history_request(Client *client, char *object, HistoryFilter *filter)
{
HistoryBackend *hb;
for (hb = historybackends; hb; hb=hb->next)
hb->history_request(client, object, filter);
return 1;
}
int history_destroy(char *object)
{
HistoryBackend *hb;
for (hb = historybackends; hb; hb=hb->next)
hb->history_destroy(object);
return 1;
}
int history_set_limit(char *object, int max_lines, long max_t)
{
HistoryBackend *hb;
for (hb = historybackends; hb; hb=hb->next)
hb->history_set_limit(object, max_lines, max_t);
return 1;
}