mirror of git://git.acid.vegas/unrealircd.git
198 lines
4.6 KiB
C
198 lines
4.6 KiB
C
|
/************************************************************************
|
||
|
* 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;
|
||
|
}
|