aqhome-cgi: more code sharing, adding page handling

allows to define your own pages with graphs, sensors and actors.
This commit is contained in:
Martin Preuss
2025-10-27 23:15:28 +01:00
parent 1b0145c97d
commit 7c5abc0f3b
9 changed files with 1205 additions and 111 deletions

View File

@@ -17,6 +17,14 @@
#include <gwenhywfar/debug.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
/* ------------------------------------------------------------------------------------------------
@@ -680,5 +688,133 @@ AQH_USER_LIST *AQH_ModService_LoadRawUsers(AQH_MODULE *m)
void AQH_ModService_EscapeToBuffer(const char *src, GWEN_BUFFER *buf)
{
while (*src) {
unsigned char x;
x=(unsigned char)*src;
if (!(
(x>='A' && x<='Z') ||
(x>='a' && x<='z') ||
(x>='0' && x<='9') ||
NULL!=strchr("-_", x)
)) {
unsigned char c;
GWEN_Buffer_AppendByte(buf, '%');
c=(((unsigned char)(*src))>>4)&0xf;
if (c>9)
c+=7;
c+='0';
GWEN_Buffer_AppendByte(buf, c);
c=((unsigned char)(*src))&0xf;
if (c>9)
c+=7;
c+='0';
GWEN_Buffer_AppendByte(buf, c);
}
else
GWEN_Buffer_AppendByte(buf, *src);
src++;
} /* while */
}
void AQH_ModService_UnescapeToBuffer(const char *src, GWEN_BUFFER *buf)
{
while (*src) {
int charHandled=0;
if (*src=='%') {
if (strlen(src)>2) {
unsigned char d1, d2;
unsigned char c;
if (isxdigit((int)src[1]) && isxdigit((int)src[2])) {
/* skip '%' */
src++;
/* read first digit */
d1=(unsigned char)(toupper(*src));
/* get second digit */
src++;
d2=(unsigned char)(toupper(*src));
/* compute character */
d1-='0';
if (d1>9)
d1-=7;
c=(d1<<4)&0xf0;
d2-='0';
if (d2>9)
d2-=7;
c+=(d2&0xf);
/* store character */
GWEN_Buffer_AppendByte(buf, (char)c);
charHandled=1;
}
}
}
if (!charHandled)
GWEN_Buffer_AppendByte(buf, *src);
src++;
} /* while */
}
int AQH_ModService_FileIsCurrent(const char *sPath, int seconds)
{
struct stat sb;
time_t t1;
if (lstat(sPath, &sb)==-1) {
DBG_ERROR(NULL, "Error on lstat(%s): %s (%d)", sPath, strerror(errno), errno);
return 0;
}
t1=time(0);
if ((t1-sb.st_mtime)<(time_t) seconds) {
DBG_DEBUG(NULL, "File %s is current", sPath);
return 1;
}
return 0;
}
int AQH_ModService_RespondWithMimeFile(AQCGI_REQUEST *rq, const char *sFilename, const char *sMimeType, GWEN_BUFFER *dbuf)
{
GWEN_BUFFER *ibuf;
int rv;
ibuf=GWEN_Buffer_new(0, 1024, 0, 1);
/* read file */
rv=GWEN_SyncIo_Helper_ReadFile(sFilename, ibuf);
if (rv<0) {
DBG_ERROR(NULL, "Error reading \"%s\" (%d)", sFilename, rv);
return rv;
}
else {
GWEN_Buffer_Reset(dbuf);
GWEN_Buffer_AppendBytes(dbuf, GWEN_Buffer_GetStart(ibuf), GWEN_Buffer_GetUsedBytes(ibuf));
if (sMimeType && *sMimeType) {
GWEN_BUFFER *tbuf;
tbuf=GWEN_Buffer_new(0, 256, 0, 1);
GBAA(tbuf, "Content-type: %s", sMimeType);
AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(tbuf));
GWEN_Buffer_free(tbuf);
}
AQCGI_Request_AddFlags(rq, AQH_MODSERVICE_RQFLAGS_RAWFILE);
}
GWEN_Buffer_free(ibuf);
return 0;
}