Version 22.49.8: Oct 18, 2022 Code refactoring related to parameters.

This commit is contained in:
acanas 2022-10-18 20:52:52 +02:00
parent 98c0490344
commit 9f6d54d0d0
8 changed files with 127 additions and 85 deletions

View File

@ -107,6 +107,20 @@ static void HTM_SELECT_BeginWithoutAttr (void);
static void HTM_SPTxt (const char *Txt);
/*****************************************************************************/
/******************************* Begin/end title *****************************/
/*****************************************************************************/
void HTM_TITLE_Begin (void)
{
fputs ("<title>",Gbl.F.Out);
}
void HTM_TITLE_End (void)
{
fputs ("</title>\n",Gbl.F.Out);
}
/*****************************************************************************/
/******************************* Begin/end table *****************************/
/*****************************************************************************/

View File

@ -58,6 +58,9 @@ typedef enum
/****************************** Public prototypes ****************************/
/*****************************************************************************/
void HTM_TITLE_Begin (void);
void HTM_TITLE_End (void);
void HTM_TABLE_Begin (const char *fmt,...);
void HTM_TABLE_BeginPadding (unsigned CellPadding);
void HTM_TABLE_BeginCenterPadding (unsigned CellPadding);

View File

@ -610,6 +610,7 @@ TODO: Attach pdf files in multimedia.
#define CSS_FILE "swad22.49.4.css"
#define JS_FILE "swad22.49.js"
/*
Version 22.49.8: Oct 18, 2022 Code refactoring related to parameters. (333253 lines)
Version 22.49.7: Oct 18, 2022 Code refactoring related to database. (333218 lines)
Version 22.49.6: Oct 18, 2022 Code refactoring related to alerts. (333197 lines)
Version 22.49.5: Oct 18, 2022 Code refactoring related to boxes. (333190 lines)

View File

@ -96,11 +96,6 @@ void Gbl_InitializeGlobals (void)
Gbl.WebService.IsWebService = false;
Gbl.Params.ContentLength = 0;
Gbl.Params.QueryString = NULL;
Gbl.Params.List = NULL;
Gbl.Params.GetMethod = false;
Gbl.F.Out = stdout;
Gbl.F.Tmp = NULL;
Gbl.F.XML = NULL;

View File

@ -74,21 +74,6 @@ struct Globals
} Config;
struct Files F;
pid_t PID; // PID of current process
struct
{
size_t ContentLength;
char *QueryString; // String allocated dynamically with the arguments sent to the CGI
struct Param *List; // Linked list of parameters
bool GetMethod; // Am I accessing using GET method?
} Params;
struct
{
char StrWithoutCRLF[Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF + 1];
char StrWithCRLF [Par_MAX_BYTES_BOUNDARY_WITH_CR_LF + 1];
size_t LengthWithoutCRLF;
size_t LengthWithCRLF;
} Boundary;
struct
{

View File

@ -442,18 +442,21 @@ static void Lay_WritePageTitle (void)
{
extern const char *Txt_TAGLINE;
HTM_Txt ("<title>");
HTM_TITLE_Begin ();
if (Gbl.Params.GetMethod && Gbl.Hierarchy.Deg.DegCod > 0)
{
HTM_TxtF ("%s &gt; %s",Cfg_PLATFORM_SHORT_NAME,Gbl.Hierarchy.Deg.ShrtName);
if (Gbl.Hierarchy.Level == HieLvl_CRS)
HTM_TxtF (" &gt; %s",Gbl.Hierarchy.Crs.ShrtName);
}
else
HTM_TxtF ("%s:&nbsp;%s",Cfg_PLATFORM_SHORT_NAME,Txt_TAGLINE);
if (Par_GetMethod () == Par_METHOD_GET &&
Gbl.Hierarchy.Deg.DegCod > 0)
{
HTM_TxtF ("%s &gt; %s",
Cfg_PLATFORM_SHORT_NAME,Gbl.Hierarchy.Deg.ShrtName);
if (Gbl.Hierarchy.Level == HieLvl_CRS)
HTM_TxtF (" &gt; %s",Gbl.Hierarchy.Crs.ShrtName);
}
else
HTM_TxtF ("%s: %s",
Cfg_PLATFORM_SHORT_NAME,Txt_TAGLINE);
HTM_Txt ("</title>\n");
HTM_TITLE_End ();
}
/*****************************************************************************/

View File

@ -53,15 +53,43 @@ extern struct Globals Gbl;
const char *Par_SEPARATOR_PARAM_MULTIPLE = "\x0a"; // Must be 1 <= character <= 31
/*****************************************************************************/
/**************************** Private constants ******************************/
/*****************************************************************************/
#define Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF (128 - 1)
#define Par_MAX_BYTES_BOUNDARY_WITH_CR_LF (2 + Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF)
/*****************************************************************************/
/************************* Private global variables **************************/
/*****************************************************************************/
/* Content send by the form and received by the CGI:
Act_CONTENT_NORM (if CONTENT_TYPE==text/plain)
Act_CONT_DATA (if CONTENT_TYPE==multipart/form-data)
*/
static Act_Content_t Par_ContentReceivedByCGI = Act_CONT_NORM;
static struct
{
/* Content send by the form and received by the CGI:
Act_CONTENT_NORM (if CONTENT_TYPE==text/plain)
Act_CONT_DATA (if CONTENT_TYPE==multipart/form-data) */
Act_Content_t ContentReceivedByCGI;
size_t ContentLength;
char *QueryString; // String allocated dynamically with the arguments sent to the CGI
struct Param *List; // Linked list of parameters
Par_Method_t Method;
bool GetMethod; // Am I accessing using GET method?
struct
{
char StrWithoutCRLF[Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF + 1];
char StrWithCRLF [Par_MAX_BYTES_BOUNDARY_WITH_CR_LF + 1];
size_t LengthWithoutCRLF;
size_t LengthWithCRLF;
} Boundary;
} Par_Params =
{
.ContentReceivedByCGI = Act_CONT_NORM,
.ContentLength = 0,
.QueryString = NULL,
.List = NULL,
.Method = Par_METHOD_POST,
};
/*****************************************************************************/
/***************************** Private prototypes ****************************/
@ -84,12 +112,12 @@ static bool Par_CheckIsParamCanBeUsedInGETMethod (const char *ParamName);
static inline void Par_SetContentReceivedByCGI (Act_Content_t ContentReceivedByCGI)
{
Par_ContentReceivedByCGI = ContentReceivedByCGI;
Par_Params.ContentReceivedByCGI = ContentReceivedByCGI;
}
Act_Content_t Par_GetContentReceivedByCGI (void)
{
return Par_ContentReceivedByCGI;
return Par_Params.ContentReceivedByCGI;
}
/*****************************************************************************/
@ -111,23 +139,25 @@ bool Par_GetQueryString (void)
if (!strcmp (Method,"GET"))
{
/***** GET method *****/
Gbl.Params.GetMethod = true;
Par_Params.Method = Par_METHOD_GET;
Par_SetContentReceivedByCGI (Act_CONT_NORM);
/* Get content length */
Gbl.Params.ContentLength = strlen (getenv ("QUERY_STRING"));
Par_Params.ContentLength = strlen (getenv ("QUERY_STRING"));
/* Allocate memory for query string */
if ((Gbl.Params.QueryString = malloc (Gbl.Params.ContentLength + 1)) == NULL)
if ((Par_Params.QueryString = malloc (Par_Params.ContentLength + 1)) == NULL)
return false;
/* Copy query string from environment variable */
Str_Copy (Gbl.Params.QueryString,getenv ("QUERY_STRING"),
Gbl.Params.ContentLength);
Str_Copy (Par_Params.QueryString,getenv ("QUERY_STRING"),
Par_Params.ContentLength);
}
else
{
/***** POST method *****/
Par_Params.Method = Par_METHOD_POST;
/* Get content length */
if (getenv ("CONTENT_LENGTH"))
{
@ -135,7 +165,7 @@ bool Par_GetQueryString (void)
sizeof (UnsignedLongStr) - 1);
if (sscanf (UnsignedLongStr,"%lu",&UnsignedLong) != 1)
return false;
Gbl.Params.ContentLength = (size_t) UnsignedLong;
Par_Params.ContentLength = (size_t) UnsignedLong;
}
else
return false;
@ -163,22 +193,28 @@ bool Par_GetQueryString (void)
Par_SetContentReceivedByCGI (Act_CONT_NORM);
/* Allocate memory for query string */
if ((Gbl.Params.QueryString = malloc (Gbl.Params.ContentLength + 1)) == NULL)
if ((Par_Params.QueryString = malloc (Par_Params.ContentLength + 1)) == NULL)
return false;
/* Copy query string from stdin */
if (fread (Gbl.Params.QueryString,sizeof (char),Gbl.Params.ContentLength,stdin) != Gbl.Params.ContentLength)
if (fread (Par_Params.QueryString,sizeof (char),
Par_Params.ContentLength,stdin) != Par_Params.ContentLength)
{
Gbl.Params.QueryString[0] = '\0';
Par_Params.QueryString[0] = '\0';
return false;
}
Gbl.Params.QueryString[Gbl.Params.ContentLength] = '\0';
Par_Params.QueryString[Par_Params.ContentLength] = '\0';
}
}
return true;
}
Par_Method_t Par_GetMethod (void)
{
return Par_Params.Method;
}
/*****************************************************************************/
/**************************** Get boundary string ****************************/
/*****************************************************************************/
@ -202,14 +238,14 @@ static void Par_GetBoundary (void)
Err_ShowErrorAndExit ("Delimiter string too long.");
/***** Create boundary strings *****/
snprintf (Gbl.Boundary.StrWithoutCRLF,sizeof (Gbl.Boundary.StrWithoutCRLF),
snprintf (Par_Params.Boundary.StrWithoutCRLF,sizeof (Par_Params.Boundary.StrWithoutCRLF),
"--%s",PtrToBoundary);
snprintf (Gbl.Boundary.StrWithCRLF,sizeof (Gbl.Boundary.StrWithCRLF),
"%c%c%s",0x0D,0x0A,Gbl.Boundary.StrWithoutCRLF);
snprintf (Par_Params.Boundary.StrWithCRLF,sizeof (Par_Params.Boundary.StrWithCRLF),
"%c%c%s",0x0D,0x0A,Par_Params.Boundary.StrWithoutCRLF);
/***** Compute lengths *****/
Gbl.Boundary.LengthWithoutCRLF = strlen (Gbl.Boundary.StrWithoutCRLF);
Gbl.Boundary.LengthWithCRLF = 2 + Gbl.Boundary.LengthWithoutCRLF;
Par_Params.Boundary.LengthWithoutCRLF = strlen (Par_Params.Boundary.StrWithoutCRLF);
Par_Params.Boundary.LengthWithCRLF = 2 + Par_Params.Boundary.LengthWithoutCRLF;
}
/*****************************************************************************/
@ -247,10 +283,10 @@ void Par_CreateListOfParams (void)
};
/***** Initialize empty list of parameters *****/
Gbl.Params.List = NULL;
Par_Params.List = NULL;
/***** Get list *****/
if (Gbl.Params.ContentLength)
if (Par_Params.ContentLength)
CreateListOfParams[Par_GetContentReceivedByCGI ()] ();
}
@ -265,13 +301,13 @@ static void Par_CreateListOfParamsFromQueryString (void)
struct Param *NewParam;
/***** Check if query string is empty *****/
if (!Gbl.Params.QueryString) return;
if (!Gbl.Params.QueryString[0]) return;
if (!Par_Params.QueryString) return;
if (!Par_Params.QueryString[0]) return;
/***** Go over the query string
getting start positions and lengths of parameters *****/
for (CurPos = 0;
CurPos < Gbl.Params.ContentLength;
CurPos < Par_Params.ContentLength;
)
{
/* Allocate space for a new parameter initialized to 0 */
@ -280,7 +316,7 @@ static void Par_CreateListOfParamsFromQueryString (void)
/* Link the previous element in list with the current element */
if (CurPos == 0)
Gbl.Params.List = NewParam; // Pointer to first param
Par_Params.List = NewParam; // Pointer to first param
else
Param->Next = NewParam; // Pointer from former param to new param
@ -289,21 +325,21 @@ static void Par_CreateListOfParamsFromQueryString (void)
/* Get parameter name */
Param->Name.Start = CurPos;
Param->Name.Length = strcspn (&Gbl.Params.QueryString[CurPos],"=");
Param->Name.Length = strcspn (&Par_Params.QueryString[CurPos],"=");
CurPos += Param->Name.Length;
/* Get parameter value */
if (CurPos < Gbl.Params.ContentLength)
if (Gbl.Params.QueryString[CurPos] == '=')
if (CurPos < Par_Params.ContentLength)
if (Par_Params.QueryString[CurPos] == '=')
{
CurPos++; // Skip '='
if (CurPos < Gbl.Params.ContentLength)
if (CurPos < Par_Params.ContentLength)
{
Param->Value.Start = CurPos;
Param->Value.Length = strcspn (&Gbl.Params.QueryString[CurPos],"&");
Param->Value.Length = strcspn (&Par_Params.QueryString[CurPos],"&");
CurPos += Param->Value.Length;
if (CurPos < Gbl.Params.ContentLength)
if (Gbl.Params.QueryString[CurPos] == '&')
if (CurPos < Par_Params.ContentLength)
if (Par_Params.QueryString[CurPos] == '&')
CurPos++; // Skip '&'
}
}
@ -334,12 +370,12 @@ static void Par_CreateListOfParamsFromTmpFile (void)
/***** Go over the file
getting start positions and lengths of parameters *****/
if (Str_ReadFileUntilBoundaryStr (Gbl.F.Tmp,NULL,
Gbl.Boundary.StrWithoutCRLF,
Gbl.Boundary.LengthWithoutCRLF,
Par_Params.Boundary.StrWithoutCRLF,
Par_Params.Boundary.LengthWithoutCRLF,
Fil_MAX_FILE_SIZE) == 1) // Delimiter string found
for (CurPos = 0;
CurPos < Gbl.Params.ContentLength;
CurPos < Par_Params.ContentLength;
)
{
/***** Skip \r\n after delimiter string *****/
@ -356,7 +392,7 @@ static void Par_CreateListOfParamsFromTmpFile (void)
/* Link the previous element in list with the current element */
if (CurPos == 0)
Gbl.Params.List = NewParam; // Pointer to first param
Par_Params.List = NewParam; // Pointer to first param
else
Param->Next = NewParam; // Pointer from former param to new param
@ -424,14 +460,14 @@ static void Par_CreateListOfParamsFromTmpFile (void)
/***** Get parameter value or file content *****/
CurPos = (unsigned long) ftell (Gbl.F.Tmp); // At start of value or file content
if (Str_ReadFileUntilBoundaryStr (Gbl.F.Tmp,NULL,
Gbl.Boundary.StrWithCRLF,
Gbl.Boundary.LengthWithCRLF,
Par_Params.Boundary.StrWithCRLF,
Par_Params.Boundary.LengthWithCRLF,
Fil_MAX_FILE_SIZE) != 1) break; // Boundary string not found
// Delimiter string found
Param->Value.Start = CurPos;
CurPos = (unsigned long) ftell (Gbl.F.Tmp); // Just after delimiter string
Param->Value.Length = CurPos - Gbl.Boundary.LengthWithCRLF -
Param->Value.Length = CurPos - Par_Params.Boundary.LengthWithCRLF -
Param->Value.Start;
}
}
@ -481,7 +517,7 @@ void Par_FreeParams (void)
struct Param *NextParam;
/***** Free list of parameters *****/
for (Param = Gbl.Params.List;
for (Param = Par_Params.List;
Param != NULL;
Param = NextParam)
{
@ -490,8 +526,8 @@ void Par_FreeParams (void)
}
/***** Free query string *****/
if (Gbl.Params.QueryString)
free (Gbl.Params.QueryString);
if (Par_Params.QueryString)
free (Par_Params.QueryString);
}
/*****************************************************************************/
@ -501,7 +537,7 @@ void Par_FreeParams (void)
// If ParamPtr is not NULL, on return it will point to the first ocurrence in list of parameters
// ParamValue can be NULL (if so, no value is copied)
unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
unsigned Par_GetParameter (Par_ParamType_t ParamType,const char *ParamName,
char *ParamValue,size_t MaxBytes,
struct Param **ParamPtr) // NULL if not used
{
@ -521,7 +557,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
ParamValue[0] = '\0'; // By default, the value of the parameter will be an empty string
/***** Only some selected parameters can be passed by GET method *****/
if (Gbl.Params.GetMethod)
if (Par_GetMethod () == Par_METHOD_GET)
if (!Par_CheckIsParamCanBeUsedInGETMethod (ParamName))
return 0; // Return no-parameters-found
@ -532,7 +568,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
/***** For multiple parameters, loop for any ocurrence of the parameter
For unique parameter, find only the first ocurrence *****/
for (Param = Gbl.Params.List, NumTimes = 0;
for (Param = Par_Params.List, NumTimes = 0;
Param != NULL && (FindMoreThanOneOcurrence || NumTimes == 0);
)
/***** Find next ocurrence of parameter in list of parameters *****/
@ -547,7 +583,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
switch (Par_GetContentReceivedByCGI ())
{
case Act_CONT_NORM:
ParamFound = !strncmp (ParamName,&Gbl.Params.QueryString[Param->Name.Start],
ParamFound = !strncmp (ParamName,&Par_Params.QueryString[Param->Name.Start],
Param->Name.Length);
break;
case Act_CONT_DATA:
@ -610,7 +646,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
{
case Act_CONT_NORM:
if (PtrDst)
strncpy (PtrDst,&Gbl.Params.QueryString[Param->Value.Start],
strncpy (PtrDst,&Par_Params.QueryString[Param->Value.Start],
Param->Value.Length);
break;
case Act_CONT_DATA:

View File

@ -36,14 +36,12 @@
/************************** Public types and constants ***********************/
/*****************************************************************************/
#define Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF (128 - 1)
#define Par_MAX_BYTES_BOUNDARY_WITH_CR_LF (2 + Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF)
struct StartLength
{
unsigned long Start;
size_t Length;
};
struct Param
{
struct StartLength Name; // Parameter name
@ -53,11 +51,17 @@ struct Param
struct Param *Next;
};
typedef enum
{
Par_METHOD_GET,
Par_METHOD_POST
} Par_Method_t;
typedef enum
{
Par_PARAM_SINGLE,
Par_PARAM_MULTIPLE,
} tParamType; // Parameter is present only one time / multiple times
} Par_ParamType_t; // Parameter is present only one time / multiple times
/*****************************************************************************/
/***************************** Public prototypes *****************************/
@ -66,9 +70,10 @@ typedef enum
Act_Content_t Par_GetContentReceivedByCGI (void);
bool Par_GetQueryString (void);
Par_Method_t Par_GetMethod (void);
void Par_CreateListOfParams (void);
void Par_FreeParams (void);
unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
unsigned Par_GetParameter (Par_ParamType_t ParamType,const char *ParamName,
char *ParamValue,size_t MaxBytes,
struct Param **ParamPtr);