added service code (used by AqHome).

This commit is contained in:
Martin Preuss
2026-05-30 18:56:14 +02:00
parent aeb0974043
commit 10475ec8af
15 changed files with 1494 additions and 2 deletions

4
0BUILD
View File

@@ -13,8 +13,8 @@
<gwbuild requiredVersion="5.6.0" > <gwbuild requiredVersion="5.6.0" >
<!-- use vtag=beta for beta versions --> <!-- use vtag=beta for beta versions -->
<project name="aqcgi" <project name="aqcgi"
vmajor="0" vminor="0" vpatchlevel="4" vbuild="0" vmajor="0" vminor="1" vpatchlevel="0" vbuild="0"
so_current="0" so_age="0" so_revision="4" so_current="1" so_age="0" so_revision="0"
write_config_h="TRUE" write_config_h="TRUE"
> >

View File

@@ -85,6 +85,7 @@
<useTargets> <useTargets>
aqhcgi_service
</useTargets> </useTargets>
@@ -94,6 +95,7 @@
<subdirs> <subdirs>
service
</subdirs> </subdirs>

95
src/aqcgi/service/0BUILD Normal file
View File

@@ -0,0 +1,95 @@
<?xml?>
<gwbuild>
<target type="ConvenienceLibrary" name="aqhcgi_service" >
<includes type="c" >
$(gwenhywfar_cflags)
-I$(topsrcdir)/src
-I$(topbuilddir)/src
-I$(topbuilddir)
-I$(topsrcdir)
-I$(srcdir)
</includes>
<includes type="tm2" >
--include=$(builddir)
--include=$(srcdir)
</includes>
<define name="BUILDING_AQCGI" />
<setVar name="local/cflags">$(visibility_cflags)</setVar>
<setVar name="tm2flags" >
--api=AQCGI_API
</setVar>
<setVar name="local/typefiles" >
module.t2d
moduleperms.t2d
role.t2d
user.t2d
session.t2d
permdef.t2d
objectdef.t2d
objectfielddef.t2d
</setVar>
<setVar name="local/built_sources" >
</setVar>
<setVar name="local/built_headers_pub">
module.h
moduleperms.h
role.h
user.h
session.h
permdef.h
objectdef.h
objectfielddef.h
</setVar>
<setVar name="local/built_headers_priv" >
</setVar>
<headers dist="false" install="$(pkgincludedir)/service" >
$(local/built_headers_pub)
</headers>
<headers dist="true" install="$(pkgincludedir)/service" >
service.h
</headers>
<headers dist="true" >
service_p.h
</headers>
<sources>
$(local/typefiles)
service.c
</sources>
<extradist>
</extradist>
<useTargets>
</useTargets>
<subdirs>
</subdirs>
</target>
</gwbuild>

20
src/aqcgi/service/README Normal file
View File

@@ -0,0 +1,20 @@
- service:
- userList
- rootModule
- sessionList
- user:
- modulePerms
- module:
- roleList
- permDefList
- session

View File

@@ -0,0 +1,103 @@
<?xml?>
<tm2>
<type id="AQCGI_MODULE" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_MODULE</identifier>
<prefix>AQCGI_Module</prefix>
<baseFileName>module</baseFileName>
<flags>
with_inherit
with_xml
with_db
with_list1
with_list2
with_tree2
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="post">aqcgi/service/role.h</header>
<header type="sys" loc="post">aqcgi/service/permdef.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQCGI_MODULE_FLAGS" prefix="AQCGI_MODULE_FLAGS_">
<item name="ACTIVE" value="0x00000001" />
</define>
</defines>
<members>
<member name="id" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="guestPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="roleList" type="AQCGI_ROLE_LIST" elementName="role" >
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
<getflags>none</getflags>
<setflags>none</setflags>
</member>
<member name="permDefList" type="AQCGI_PERMDEF_LIST" elementName="permdef" >
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
<getflags>none</getflags>
<setflags>none</setflags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,67 @@
<?xml?>
<tm2>
<type id="AQCGI_MODULE_PERMS" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_MODULE_PERMS</identifier>
<prefix>AQCGI_ModulePerms</prefix>
<baseFileName>moduleperms</baseFileName>
<flags>
with_inherit
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="post">aqcgi/service/role.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="moduleId" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="explAddPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explDelPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="roleArray" type="uint8_t_array" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,72 @@
<?xml?>
<tm2>
<type id="AQCGI_OBJECT_DEF" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_OBJECT_DEF</identifier>
<prefix>AQCGI_ObjectDef</prefix>
<baseFileName>objectdef</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">aqcgi/service/objectfielddef.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQCGI_OBJECT_FLAGS" prefix="AQCGI_OBJECT_FLAGS_">
<item name="HASTEXT" value="0x00000001" />
</define>
</defines>
<members>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="label" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="fieldDefList" type="AQCGI_OBJECT_FIELD_DEF_LIST" maxlen="4">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,108 @@
<?xml?>
<tm2>
<type id="AQCGI_OBJECT_FIELD_DEF" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_OBJECT_FIELD_DEF</identifier>
<prefix>AQCGI_ObjectFieldDef</prefix>
<baseFileName>objectfielddef</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQCGI_OBJECTFIELD_FLAGS" prefix="AQCGI_OBJECTFIELD_FLAGS_">
<item name="IMMUTABLE" value="0x00000001" />
<item name="REQUIRED" value="0x00000002" />
</define>
</defines>
<enums>
<enum id="AQCGI_OBJECTFIELD_TYPE" prefix="AQCGI_ObjectFieldType_">
<item name="bool">
<descr>boolean</descr>
</item>
<item name="int">
<descr>Integer</descr>
</item>
<item name="string">
<descr>string</descr>
</item>
<item name="date">
<descr>date</descr>
</item>
<item name="choice">
<descr>choice</descr>
</item>
</enum>
</enums>
<members>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="label" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="dataType" type="int" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="choices" type="char_ptr" maxlen="256">
<descr>Semicolon separated list of choices</descr>
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,65 @@
<?xml?>
<tm2>
<type id="AQCGI_PERMDEF" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_PERMDEF</identifier>
<prefix>AQCGI_PermDef</prefix>
<baseFileName>permdef</baseFileName>
<flags>
with_xml
with_db
with_list1
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="id" type="char_ptr" maxlen="32">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="32">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="mask" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
</members>
</type>
</tm2>

View File

@@ -0,0 +1,79 @@
<?xml?>
<tm2>
<type id="AQCGI_ROLE" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_ROLE</identifier>
<prefix>AQCGI_Role</prefix>
<baseFileName>role</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
</headers>
<inlines>
</inlines>
</lang>
<members>
<member name="id" type="uint8_t" maxlen="1">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="descr" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="perms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explAddPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="explDelPerms" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
</members>
</type>
</tm2>

432
src/aqcgi/service/service.c Normal file
View File

@@ -0,0 +1,432 @@
/****************************************************************************
* This file is part of the project AqCGI.
* AqCGI (c) by 2026 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
//#define DISABLE_DEBUGLOG
#include "aqcgi/service/service_p.h"
#include <gwenhywfar/stringlist.h>
#include <gwenhywfar/text.h>
#include <gwenhywfar/debug.h>
GWEN_INHERIT_FUNCTIONS(AQCGI_SERVICE);
GWEN_LIST_FUNCTIONS(AQCGI_SERVICE, AQCGI_Service);
AQCGI_SERVICE *AQCGI_Service_new(const char *baseFolder, const char *baseUrl)
{
AQCGI_SERVICE *sv;
GWEN_NEW_OBJECT(AQCGI_SERVICE, sv);
GWEN_INHERIT_INIT(AQCGI_SERVICE, sv);
GWEN_LIST_INIT(AQCGI_SERVICE, sv);
sv->baseUrl=baseUrl?strdup(baseUrl):NULL;
sv->baseFolder=baseFolder?strdup(baseFolder):NULL;
if (sv->baseFolder) {
GWEN_BUFFER *dbuf;
uint32_t pos;
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
GWEN_Buffer_AppendArgs(dbuf, "%s%s", sv->baseFolder, GWEN_DIR_SEPARATOR_S);
pos=GWEN_Buffer_GetPos(dbuf);
/* data folder */
GWEN_Buffer_AppendString(dbuf, "data");
sv->runtimeFolder=strdup(GWEN_Buffer_GetStart(dbuf));
DBG_ERROR(NULL, "Runtime folder: %s", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_Crop(dbuf, 0, pos);
/* cache folder */
GWEN_Buffer_AppendString(dbuf, "cache");
sv->cacheFolder=strdup(GWEN_Buffer_GetStart(dbuf));
DBG_ERROR(NULL, "Cache folder: %s", GWEN_Buffer_GetStart(dbuf));
GWEN_Buffer_Crop(dbuf, 0, pos);
GWEN_Buffer_free(dbuf);
}
return sv;
}
void AQCGI_Service_free(AQCGI_SERVICE *sv)
{
if (sv) {
GWEN_LIST_FINI(AQCGI_SERVICE, sv);
GWEN_INHERIT_FINI(AQCGI_SERVICE, sv);
free(sv->baseUrl);
free(sv->baseFolder);
free(sv->runtimeFolder);
free(sv->cacheFolder);
free(sv->loginUrl);
GWEN_FREE_OBJECT(sv);
}
}
const char *AQCGI_Service_GetBaseUrl(const AQCGI_SERVICE *sv)
{
return sv?sv->baseUrl:NULL;
}
const char *AQCGI_Service_GetBaseFolder(const AQCGI_SERVICE *sv)
{
return sv?sv->baseFolder:NULL;
}
const char *AQCGI_Service_GetRuntimeFolder(const AQCGI_SERVICE *sv)
{
return sv?sv->runtimeFolder:NULL;
}
const char *AQCGI_Service_GetCacheFolder(const AQCGI_SERVICE *sv)
{
return sv?sv->cacheFolder:NULL;
}
const char *AQCGI_Service_GetLoginUrl(const AQCGI_SERVICE *sv)
{
return sv?sv->loginUrl:NULL;
}
void AQCGI_Service_SetLoginUrl(AQCGI_SERVICE *sv, const char *s)
{
if (sv) {
free(sv->loginUrl);
sv->loginUrl=s?strdup(s):NULL;
}
}
#if 0
AQCGI_MODULE *AQCGI_Service_GetModuleByPath(const AQCGI_SERVICE *sv, const char *s)
{
if (sv && s && *s) {
GWEN_STRINGLIST *sl;
sl=GWEN_StringList_fromString2(s, "/", 0,
GWEN_TEXT_FLAGS_DEL_QUOTES |
GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS |
GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS |
GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS);
if (sl) {
GWEN_STRINGLISTENTRY *se;
AQCGI_MODULE *m;
m=sv->rootModule;
se=GWEN_StringList_FirstEntry(sl);
while(se && m) {
const char *sWantedName;
sWantedName=GWEN_StringListEntry_Data(se);
if (sWantedName && *sWantedName) {
AQCGI_MODULE *mTemp;
mTemp=AQCGI_Module_Tree2_GetFirstChild(m);
while(mTemp) {
const char *sModName;
sModName=AQCGI_Module_GetName(mTemp);
if (sModName && *sModName && 0==strcasecmp(sModName, sWantedName))
break;
mTemp=AQCGI_Module_Tree2_GetNext(mTemp);
}
if (mTemp==NULL) {
DBG_ERROR(NULL, "Module \%s\" not found", sWantedName);
GWEN_StringList_free(sl);
return NULL;
}
m=mTemp;
}
else {
DBG_ERROR(NULL, "Empty path element in \"%s\"", s);
GWEN_StringList_free(sl);
return NULL;
}
se=GWEN_StringListEntry_Next(se);
} /* while(se && m) */
GWEN_StringList_free(sl);
return m;
}
else {
DBG_ERROR(NULL, "Bad path \"%s\"", s);
}
}
return NULL;
}
#endif
int AQCGI_Service_HandleRequest(AQCGI_SERVICE *sv, AQCGI_REQUEST *req)
{
return (sv && sv->handleRequestFn)?(sv->handleRequestFn(sv, req)):GWEN_ERROR_NOT_IMPLEMENTED;
}
AQCGI_USER *AQCGI_Service_LoadUser(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->loadUserFn)?(sv->loadUserFn(sv, s)):NULL;
}
int AQCGI_Service_SaveUser(AQCGI_SERVICE *sv, AQCGI_USER *user)
{
return (sv && sv->saveUserFn)?(sv->saveUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_AddUser(AQCGI_SERVICE *sv, AQCGI_USER *user)
{
return (sv && sv->addUserFn)?(sv->addUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_DelUser(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->delUserFn)?(sv->delUserFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
GWEN_STRINGLIST *AQCGI_Service_ListUsers(AQCGI_SERVICE *sv)
{
return (sv && sv->listUsersFn)?(sv->listUsersFn(sv)):NULL;
}
AQCGI_MODULE *AQCGI_Service_LoadModule(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->loadModuleFn)?(sv->loadModuleFn(sv, s)):NULL;
}
int AQCGI_Service_SaveModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module)
{
return (sv && sv->saveModuleFn)?(sv->saveModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_AddModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module)
{
return (sv && sv->addModuleFn)?(sv->addModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_DelModule(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->delModuleFn)?(sv->delModuleFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
GWEN_STRINGLIST *AQCGI_Service_ListModules(AQCGI_SERVICE *sv)
{
return (sv && sv->listModulesFn)?(sv->listModulesFn(sv)):NULL;
}
AQCGI_SESSION* AQCGI_Service_LoadSession(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->loadSessionFn)?(sv->loadSessionFn(sv, s)):NULL;
}
int AQCGI_Service_SaveSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session)
{
return (sv && sv->saveSessionFn)?(sv->saveSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_AddSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session)
{
return (sv && sv->addSessionFn)?(sv->addSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}
int AQCGI_Service_DelSession(AQCGI_SERVICE *sv, const char *s)
{
return (sv && sv->delSessionFn)?(sv->delSessionFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}
void AQCGI_Service_SetHandleRequestFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_HANDLEREQUEST_FN f)
{
if (sv)
sv->handleRequestFn=f;
}
void AQCGI_Service_SetLoadUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADUSER_FN f)
{
if (sv)
sv->loadUserFn=f;
}
void AQCGI_Service_SetSaveUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVEUSER_FN f)
{
if (sv)
sv->saveUserFn=f;
}
void AQCGI_Service_SetAddUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDUSER_FN f)
{
if (sv)
sv->addUserFn=f;
}
void AQCGI_Service_SetDelUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELUSER_FN f)
{
if (sv)
sv->delUserFn=f;
}
void AQCGI_Service_SetListUsersFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTUSERS_FN f)
{
if (sv)
sv->listUsersFn=f;
}
void AQCGI_Service_SetLoadModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADMODULE_FN f)
{
if (sv)
sv->loadModuleFn=f;
}
void AQCGI_Service_SetSaveModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVEMODULE_FN f)
{
if (sv)
sv->saveModuleFn=f;
}
void AQCGI_Service_SetAddModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDMODULE_FN f)
{
if (sv)
sv->addModuleFn=f;
}
void AQCGI_Service_SetDelModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELMODULE_FN f)
{
if (sv)
sv->delModuleFn=f;
}
void AQCGI_Service_SetListModulesFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTMODULES_FN f)
{
if (sv)
sv->listModulesFn=f;
}
void AQCGI_Service_SetLoadSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADSESSION_FN f)
{
if (sv)
sv->loadSessionFn=f;
}
void AQCGI_Service_SetSaveSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVESESSION_FN f)
{
if (sv)
sv->saveSessionFn=f;
}
void AQCGI_Service_SetAddSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDSESSION_FN f)
{
if (sv)
sv->addSessionFn=f;
}
void AQCGI_Service_SetDelSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELSESSION_FN f)
{
if (sv)
sv->delSessionFn=f;
}
void AQCGI_Service_SetListSessionsFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTSESSIONS_FN f)
{
if (sv)
sv->listSessionsFn=f;
}

109
src/aqcgi/service/service.h Normal file
View File

@@ -0,0 +1,109 @@
/****************************************************************************
* This file is part of the project AqCGI.
* AqCGI (c) by 2026 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQCGI_SERVICE_SERVICE_H
#define AQCGI_SERVICE_SERVICE_H
#include <aqcgi/api.h>
#include <gwenhywfar/inherit.h>
#include <gwenhywfar/list.h>
#include <gwenhywfar/stringlist.h>
typedef struct AQCGI_SERVICE AQCGI_SERVICE;
GWEN_INHERIT_FUNCTION_LIB_DEFS(AQCGI_SERVICE, AQCGI_API);
GWEN_LIST_FUNCTION_LIB_DEFS(AQCGI_SERVICE, AQCGI_Service, AQCGI_API);
#include "aqcgi/service/user.h"
#include "aqcgi/service/module.h"
#include "aqcgi/service/session.h"
#include <aqcgi/cgi.h>
typedef int (*AQCGI_SERVICE_HANDLEREQUEST_FN)(AQCGI_SERVICE *sv, AQCGI_REQUEST *req);
typedef AQCGI_USER* (*AQCGI_SERVICE_LOADUSER_FN)(AQCGI_SERVICE *sv, const char *s);
typedef int (*AQCGI_SERVICE_SAVEUSER_FN)(AQCGI_SERVICE *sv, AQCGI_USER *user);
typedef int (*AQCGI_SERVICE_ADDUSER_FN)(AQCGI_SERVICE *sv, AQCGI_USER *user);
typedef int (*AQCGI_SERVICE_DELUSER_FN)(AQCGI_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQCGI_SERVICE_LISTUSERS_FN)(AQCGI_SERVICE *sv);
typedef AQCGI_MODULE* (*AQCGI_SERVICE_LOADMODULE_FN)(AQCGI_SERVICE *sv, const char *s);
typedef int (*AQCGI_SERVICE_SAVEMODULE_FN)(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
typedef int (*AQCGI_SERVICE_ADDMODULE_FN)(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
typedef int (*AQCGI_SERVICE_DELMODULE_FN)(AQCGI_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQCGI_SERVICE_LISTMODULES_FN)(AQCGI_SERVICE *sv);
typedef AQCGI_SESSION* (*AQCGI_SERVICE_LOADSESSION_FN)(AQCGI_SERVICE *sv, const char *s);
typedef int (*AQCGI_SERVICE_SAVESESSION_FN)(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
typedef int (*AQCGI_SERVICE_ADDSESSION_FN)(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
typedef int (*AQCGI_SERVICE_DELSESSION_FN)(AQCGI_SERVICE *sv, const char *s);
typedef GWEN_STRINGLIST* (*AQCGI_SERVICE_LISTSESSIONS_FN)(AQCGI_SERVICE *sv);
AQCGI_API AQCGI_SERVICE *AQCGI_Service_new(const char *baseFolder, const char *baseUrl);
AQCGI_API void AQCGI_Service_free(AQCGI_SERVICE *sv);
AQCGI_API const char *AQCGI_Service_GetBaseUrl(const AQCGI_SERVICE *sv);
AQCGI_API const char *AQCGI_Service_GetLoginUrl(const AQCGI_SERVICE *sv);
AQCGI_API void AQCGI_Service_SetLoginUrl(AQCGI_SERVICE *sv, const char *s);
AQCGI_API const char *AQCGI_Service_GetBaseFolder(const AQCGI_SERVICE *sv);
AQCGI_API const char *AQCGI_Service_GetRuntimeFolder(const AQCGI_SERVICE *sv);
AQCGI_API const char *AQCGI_Service_GetCacheFolder(const AQCGI_SERVICE *sv);
AQCGI_API int AQCGI_Service_HandleRequest(AQCGI_SERVICE *sv, AQCGI_REQUEST *req);
AQCGI_API AQCGI_USER *AQCGI_Service_LoadUser(AQCGI_SERVICE *sv, const char *s);
AQCGI_API int AQCGI_Service_SaveUser(AQCGI_SERVICE *sv, AQCGI_USER *user);
AQCGI_API int AQCGI_Service_AddUser(AQCGI_SERVICE *sv, AQCGI_USER *user);
AQCGI_API int AQCGI_Service_DelUser(AQCGI_SERVICE *sv, const char *s);
AQCGI_API GWEN_STRINGLIST *AQCGI_Service_ListUsers(AQCGI_SERVICE *sv);
AQCGI_API AQCGI_MODULE *AQCGI_Service_LoadModule(AQCGI_SERVICE *sv, const char *s);
AQCGI_API int AQCGI_Service_SaveModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
AQCGI_API int AQCGI_Service_AddModule(AQCGI_SERVICE *sv, AQCGI_MODULE *module);
AQCGI_API int AQCGI_Service_DelModule(AQCGI_SERVICE *sv, const char *s);
AQCGI_API GWEN_STRINGLIST *AQCGI_Service_ListModules(AQCGI_SERVICE *sv);
AQCGI_API AQCGI_SESSION* AQCGI_Service_LoadSession(AQCGI_SERVICE *sv, const char *s);
AQCGI_API int AQCGI_Service_SaveSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
AQCGI_API int AQCGI_Service_AddSession(AQCGI_SERVICE *sv, AQCGI_SESSION *session);
AQCGI_API int AQCGI_Service_DelSession(AQCGI_SERVICE *sv, const char *s);
AQCGI_API GWEN_STRINGLIST *AQCGI_Service_ListSessions(AQCGI_SERVICE *sv);
AQCGI_API void AQCGI_Service_SetHandleRequestFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_HANDLEREQUEST_FN f);
AQCGI_API void AQCGI_Service_SetLoadUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADUSER_FN f);
AQCGI_API void AQCGI_Service_SetSaveUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVEUSER_FN f);
AQCGI_API void AQCGI_Service_SetAddUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDUSER_FN f);
AQCGI_API void AQCGI_Service_SetDelUserFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELUSER_FN f);
AQCGI_API void AQCGI_Service_SetListUsersFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTUSERS_FN f);
AQCGI_API void AQCGI_Service_SetLoadModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADMODULE_FN f);
AQCGI_API void AQCGI_Service_SetSaveModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVEMODULE_FN f);
AQCGI_API void AQCGI_Service_SetAddModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDMODULE_FN f);
AQCGI_API void AQCGI_Service_SetDelModuleFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELMODULE_FN f);
AQCGI_API void AQCGI_Service_SetListModulesFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTMODULES_FN f);
AQCGI_API void AQCGI_Service_SetLoadSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LOADSESSION_FN f);
AQCGI_API void AQCGI_Service_SetSaveSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_SAVESESSION_FN f);
AQCGI_API void AQCGI_Service_SetAddSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_ADDSESSION_FN f);
AQCGI_API void AQCGI_Service_SetDelSessionFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_DELSESSION_FN f);
AQCGI_API void AQCGI_Service_SetListSessionsFn(AQCGI_SERVICE *sv, AQCGI_SERVICE_LISTSESSIONS_FN f);
#endif

View File

@@ -0,0 +1,52 @@
/****************************************************************************
* This file is part of the project AqCGI.
* AqCGI (c) by 2026 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/
#ifndef AQCGI_SERVICE_SERVICE_P_H
#define AQCGI_SERVICE_SERVICE_P_H
#include "aqcgi/service/service.h"
struct AQCGI_SERVICE {
GWEN_INHERIT_ELEMENT(AQCGI_SERVICE);
GWEN_LIST_ELEMENT(AQCGI_SERVICE);
char *baseUrl;
char *baseFolder;
char *runtimeFolder;
char *cacheFolder;
char *loginUrl;
AQCGI_SERVICE_HANDLEREQUEST_FN handleRequestFn;
AQCGI_SERVICE_LOADUSER_FN loadUserFn;
AQCGI_SERVICE_SAVEUSER_FN saveUserFn;
AQCGI_SERVICE_ADDUSER_FN addUserFn;
AQCGI_SERVICE_DELUSER_FN delUserFn;
AQCGI_SERVICE_LISTUSERS_FN listUsersFn;
AQCGI_SERVICE_LOADMODULE_FN loadModuleFn;
AQCGI_SERVICE_SAVEMODULE_FN saveModuleFn;
AQCGI_SERVICE_ADDMODULE_FN addModuleFn;
AQCGI_SERVICE_DELMODULE_FN delModuleFn;
AQCGI_SERVICE_LISTMODULES_FN listModulesFn;
AQCGI_SERVICE_LOADSESSION_FN loadSessionFn;
AQCGI_SERVICE_SAVESESSION_FN saveSessionFn;
AQCGI_SERVICE_ADDSESSION_FN addSessionFn;
AQCGI_SERVICE_DELSESSION_FN delSessionFn;
AQCGI_SERVICE_LISTSESSIONS_FN listSessionsFn;
};
#endif

View File

@@ -0,0 +1,117 @@
<?xml?>
<tm2>
<type id="AQCGI_SESSION" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_SESSION</identifier>
<prefix>AQCGI_Session</prefix>
<baseFileName>session</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="pre">gwenhywfar/timestamp.h</header>
<header type="sys" loc="post">aqcgi/service/user.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQCGI_SESSION_RTFLAGS" prefix="AQCGI_SESSION_RTFLAGS_">
<item name="MODIFIED" value="0x00000001" />
</define>
</defines>
<members>
<member name="uid" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="userAlias" type="char_ptr" maxlen="64">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="state" type="int" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags></flags>
</member>
<member name="tempToken" type="char_ptr" maxlen="64">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampLastAccess" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="user" type="AQCGI_USER">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<setflags>assign</setflags>
<getflags>none</getflags>
<flags>volatile nodup nocopy</flags>
</member>
<member name="runtimeFlags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags volatile</flags>
</member>
</members>
</type>
</tm2>

171
src/aqcgi/service/user.t2d Normal file
View File

@@ -0,0 +1,171 @@
<?xml?>
<tm2>
<type id="AQCGI_USER" type="pointer">
<descr>
</descr>
<lang id="c">
<identifier>AQCGI_USER</identifier>
<prefix>AQCGI_User</prefix>
<baseFileName>user</baseFileName>
<flags>
with_xml
with_db
with_list1
with_list2
with_refcount
nodup
nocopy
</flags>
<headers>
<header type="sys" loc="pre">aqcgi/api.h</header>
<header type="sys" loc="pre">gwenhywfar/error.h</header>
<header type="sys" loc="pre">gwenhywfar/timestamp.h</header>
<header type="sys" loc="post">aqcgi/service/moduleperms.h</header>
</headers>
<inlines>
</inlines>
</lang>
<defines>
<define id="AQCGI_USER_FLAGS" prefix="AQCGI_USER_FLAGS_">
<item name="ADMIN" value="0x00000001" />
</define>
<define id="AQCGI_USER_RTFLAGS" prefix="AQCGI_USER_RTFLAGS_">
<item name="MODIFIED" value="0x00000001" />
<item name="PERMSCALC" value="0x00000002" />
</define>
</defines>
<enums>
<enum id="AQCGI_USER_STATE" prefix="AQCGI_UserState_">
<item name="suspended">
<descr>User suspended</descr>
</item>
<item name="waitForConfirmation">
<descr>Waiting for email confirmation</descr>
</item>
<item name="waitForApproval">
<descr>Waiting for approval by admin</descr>
</item>
<item name="active">
<descr>User active</descr>
</item>
</enum>
</enums>
<members>
<member name="id" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_getbymember sortbymember</flags>
</member>
<member name="flags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>with_flags</flags>
</member>
<member name="state" type="int" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>sortbymember</flags>
</member>
<member name="name" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="alias" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="lang" type="char_ptr" maxlen="16">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="hashedPassword" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="email" type="char_ptr" maxlen="128">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own with_getbymember sortbymember</flags>
</member>
<member name="notes" type="char_ptr" maxlen="256">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>own</flags>
</member>
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="timestampLastLogin" type="gwen_timestamp" maxlen="8">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<flags>own sortbymember</flags>
</member>
<member name="modulePermList" type="AQCGI_MODULE_PERMS_LIST">
<default>NULL</default>
<preset>NULL</preset>
<access>public</access>
<getflags>none</getflags>
<setflags>none</setflags>
<flags>own</flags>
</member>
<member name="runtimeFlags" type="uint32_t" maxlen="4">
<default>0</default>
<preset>0</preset>
<access>public</access>
<flags>volatile with_flags</flags>
</member>
</members>
</type>
</tm2>