Version 22.51: Oct 27, 2022 New module swad_process.

This commit is contained in:
acanas 2022-10-27 22:09:44 +02:00
parent 96ecc72a50
commit a63d68f746
34 changed files with 384 additions and 268 deletions

View File

@ -76,7 +76,7 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
swad_pagination.o swad_parameter.o swad_password.o \ swad_pagination.o swad_parameter.o swad_password.o \
swad_password_database.o swad_photo.o swad_photo_database.o \ swad_password_database.o swad_photo.o swad_photo_database.o \
swad_photo_shape.o swad_place.o swad_place_database.o swad_plugin.o \ swad_photo_shape.o swad_place.o swad_place_database.o swad_plugin.o \
swad_plugin_database.o swad_privacy.o swad_profile.o \ swad_plugin_database.o swad_privacy.o swad_process.o swad_profile.o \
swad_profile_database.o swad_program.o swad_program_database.o \ swad_profile_database.o swad_program.o swad_program_database.o \
swad_program_resource.o swad_project.o swad_project_database.o \ swad_program_resource.o swad_project.o swad_project_database.o \
swad_project_resource.o \ swad_project_resource.o \

View File

@ -114,12 +114,12 @@ static void HTM_SPTxt (const char *Txt);
void HTM_TITLE_Begin (void) void HTM_TITLE_Begin (void)
{ {
fputs ("<title>",Gbl.F.Out); HTM_Txt ("<title>");
} }
void HTM_TITLE_End (void) void HTM_TITLE_End (void)
{ {
fputs ("</title>\n",Gbl.F.Out); HTM_Txt ("</title>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1871,7 +1871,7 @@ void HTM_Txt (const char *Txt)
{ {
if (Txt) if (Txt)
if (Txt[0]) if (Txt[0])
fputs (Txt,Gbl.F.Out); fputs (Txt,Fil_GetOutputFile ());
} }
void HTM_TxtColon (const char *Txt) void HTM_TxtColon (const char *Txt)

View File

@ -605,7 +605,7 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate
TODO: Attach pdf files in multimedia. TODO: Attach pdf files in multimedia.
*/ */
#define Log_PLATFORM_VERSION "SWAD 22.50.7 (2022-10-21)" #define Log_PLATFORM_VERSION "SWAD 22.51 (2022-10-27)"
#define CSS_FILE "swad22.49.4.css" #define CSS_FILE "swad22.49.4.css"
#define JS_FILE "swad22.49.js" #define JS_FILE "swad22.49.js"
/* /*
@ -616,6 +616,8 @@ Que al subir un fichero por defecto est
Al subir cosas para los grupos, en documentos, resltar más los grupos porque no son conscientes... Al subir cosas para los grupos, en documentos, resltar más los grupos porque no son conscientes...
Exportar listas en CSV. Exportar listas en CSV.
Version 22.51: Oct 27, 2022 New module swad_process. (333586 lines)
Version 22.50.8: Oct 20, 2022 Code refactoring in files. (333498 lines)
Version 22.50.7: Oct 20, 2022 Code refactoring in files. (333496 lines) Version 22.50.7: Oct 20, 2022 Code refactoring in files. (333496 lines)
Version 22.50.6: Oct 20, 2022 Code refactoring in syllabus. (333492 lines) Version 22.50.6: Oct 20, 2022 Code refactoring in syllabus. (333492 lines)
Version 22.50.5: Oct 20, 2022 Code refactoring in configuration. (333447 lines) Version 22.50.5: Oct 20, 2022 Code refactoring in configuration. (333447 lines)

View File

@ -386,6 +386,7 @@ void Cht_OpenChatWindow (void)
char ListRoomShrtNames[Cht_MAX_BYTES_ROOM_SHRT_NAMES + 1]; char ListRoomShrtNames[Cht_MAX_BYTES_ROOM_SHRT_NAMES + 1];
char ListRoomFullNames [Cht_MAX_BYTES_ROOM_FULL_NAMES + 1]; char ListRoomFullNames [Cht_MAX_BYTES_ROOM_FULL_NAMES + 1];
FILE *FileChat; FILE *FileChat;
FILE *FileOut = Fil_GetOutputFile ();
/***** Get the code and the nombre of the room *****/ /***** Get the code and the nombre of the room *****/
Par_GetParToText ("RoomCode",RoomCode,Cht_MAX_BYTES_ROOM_CODE); Par_GetParToText ("RoomCode",RoomCode,Cht_MAX_BYTES_ROOM_CODE);
@ -525,15 +526,15 @@ void Cht_OpenChatWindow (void)
Gbl.Layout.HTMLStartWritten = true; Gbl.Layout.HTMLStartWritten = true;
/***** Copy index.html file until the end of the applet code *****/ /***** Copy index.html file until the end of the applet code *****/
Str_WriteUntilStrFoundInFileIncludingStr (Gbl.F.Out,FileChat,"<applet", Str_WriteUntilStrFoundInFileIncludingStr (FileOut,FileChat,"<applet",
Str_NO_SKIP_HTML_COMMENTS); Str_NO_SKIP_HTML_COMMENTS);
Str_WriteUntilStrFoundInFileIncludingStr (Gbl.F.Out,FileChat,">", Str_WriteUntilStrFoundInFileIncludingStr (FileOut,FileChat,">",
Str_NO_SKIP_HTML_COMMENTS); Str_NO_SKIP_HTML_COMMENTS);
/***** Write parameters *****/ /***** Write parameters *****/
HTM_PARAM ("nick","N%s",Gbl.Session.Id); HTM_PARAM ("nick","N%s",Gbl.Session.Id);
HTM_PARAM ("realname","%s",UsrName); HTM_PARAM ("realname","%s",UsrName);
HTM_PARAM ("host","%s",Gbl.IP); HTM_PARAM ("host","%s",Par_GetIP ());
HTM_PARAM ("server_name","%s",Cfg_PLATFORM_SERVER); HTM_PARAM ("server_name","%s",Cfg_PLATFORM_SERVER);
HTM_PARAM ("port","%u",5000); HTM_PARAM ("port","%u",5000);
HTM_PARAM ("image_bl","%s/usr_bl.jpg",Cfg_URL_ICON_PUBLIC); HTM_PARAM ("image_bl","%s/usr_bl.jpg",Cfg_URL_ICON_PUBLIC);
@ -543,7 +544,7 @@ void Cht_OpenChatWindow (void)
HTM_PARAM ("topic","%s",ListRoomFullNames); HTM_PARAM ("topic","%s",ListRoomFullNames);
/***** Copy index.html file until the end *****/ /***** Copy index.html file until the end *****/
Str_WriteUntilStrFoundInFileIncludingStr (Gbl.F.Out,FileChat,"</html>", Str_WriteUntilStrFoundInFileIncludingStr (FileOut,FileChat,"</html>",
Str_NO_SKIP_HTML_COMMENTS); Str_NO_SKIP_HTML_COMMENTS);
/***** Close index.html file *****/ /***** Close index.html file *****/

View File

@ -36,12 +36,6 @@
#define Cns_MAX_CHARS_WWW (256 - 1) // 255: max. number of chars of a URL #define Cns_MAX_CHARS_WWW (256 - 1) // 255: max. number of chars of a URL
#define Cns_MAX_BYTES_WWW Cns_MAX_CHARS_WWW // 255 #define Cns_MAX_BYTES_WWW Cns_MAX_CHARS_WWW // 255
#define Cns_MAX_CHARS_IP (3 + 1 + 3 + 1 + 3 + 1 + 3) // 15: max. number of chars of an IP address
// Example: 255.255.255.255
// 3+1+3+1+3+1+3
// 123456789012345
#define Cns_MAX_BYTES_IP Cns_MAX_CHARS_IP // 15
#define Cns_MAX_CHARS_DATE (16 - 1) // 15 #define Cns_MAX_CHARS_DATE (16 - 1) // 15
#define Cns_MAX_BYTES_DATE ((Cns_MAX_CHARS_DATE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 255 #define Cns_MAX_BYTES_DATE ((Cns_MAX_CHARS_DATE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 255

View File

@ -32,6 +32,8 @@
#include "swad_constant.h" #include "swad_constant.h"
#include "swad_cryptography.h" #include "swad_cryptography.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_parameter.h"
#include "swad_process.h"
/*****************************************************************************/ /*****************************************************************************/
/**************************** Private constants ******************************/ /**************************** Private constants ******************************/
@ -133,16 +135,16 @@ void Cry_EncryptSHA512Base64 (const char *PlainText,
void Cry_CreateUniqueNameEncrypted (char *UniqueNameEncrypted) void Cry_CreateUniqueNameEncrypted (char *UniqueNameEncrypted)
{ {
static unsigned NumCall = 0; // When this function is called several times in the same execution of the program, each time a new name is created static unsigned NumCall = 0; // When this function is called several times in the same execution of the program, each time a new name is created
char UniqueNamePlain[Cns_MAX_BYTES_IP + char UniqueNamePlain[Par_MAX_BYTES_IP +
Cns_MAX_DECIMAL_DIGITS_LONG + Cns_MAX_DECIMAL_DIGITS_LONG +
Cns_MAX_DECIMAL_DIGITS_LONG + Cns_MAX_DECIMAL_DIGITS_LONG +
Cns_MAX_DECIMAL_DIGITS_UINT + 1]; Cns_MAX_DECIMAL_DIGITS_UINT + 1];
NumCall++; NumCall++;
snprintf (UniqueNamePlain,sizeof (UniqueNamePlain),"%s-%lx-%lx-%x", snprintf (UniqueNamePlain,sizeof (UniqueNamePlain),"%s-%lx-%lx-%x",
Gbl.IP, Par_GetIP (),
(long) Dat_GetStartExecutionTimeUTC (), (long) Dat_GetStartExecutionTimeUTC (),
(long) Gbl.PID, (long) Prc_GetPID (),
NumCall); NumCall);
Cry_EncryptSHA256Base64 (UniqueNamePlain,UniqueNameEncrypted); // Make difficult to guess a unique name Cry_EncryptSHA256Base64 (UniqueNamePlain,UniqueNameEncrypted); // Make difficult to guess a unique name
} }

View File

@ -1199,7 +1199,7 @@ mysql> DESCRIBE exa_log;
"QstInd INT NOT NULL DEFAULT -1," "QstInd INT NOT NULL DEFAULT -1,"
"CanAnswer ENUM('N','Y') NOT NULL DEFAULT 'N'," "CanAnswer ENUM('N','Y') NOT NULL DEFAULT 'N',"
"ClickTime DATETIME NOT NULL," "ClickTime DATETIME NOT NULL,"
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"UNIQUE INDEX(LogCod)," "UNIQUE INDEX(LogCod),"
"UNIQUE INDEX(PrnCod,LogCod)," "UNIQUE INDEX(PrnCod,LogCod),"
"INDEX(ClickTime))"); "INDEX(ClickTime))");
@ -1445,7 +1445,7 @@ mysql> DESCRIBE fir_banned;
3 rows in set (0.00 sec) 3 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS fir_banned (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS fir_banned ("
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"BanTime DATETIME NOT NULL," "BanTime DATETIME NOT NULL,"
"UnbanTime DATETIME NOT NULL," "UnbanTime DATETIME NOT NULL,"
"INDEX(IP,UnbanTime)," "INDEX(IP,UnbanTime),"
@ -1465,7 +1465,7 @@ mysql> DESCRIBE fir_log;
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS fir_log (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS fir_log ("
"ClickTime DATETIME NOT NULL," "ClickTime DATETIME NOT NULL,"
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"INDEX(ClickTime)," "INDEX(ClickTime),"
"INDEX(IP))"); "INDEX(IP))");
@ -2072,7 +2072,7 @@ mysql> DESCRIBE log_recent;
"ClickTime DATETIME NOT NULL," "ClickTime DATETIME NOT NULL,"
"TimeToGenerate INT NOT NULL," "TimeToGenerate INT NOT NULL,"
"TimeToSend INT NOT NULL," "TimeToSend INT NOT NULL,"
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"UNIQUE INDEX(LogCod)," "UNIQUE INDEX(LogCod),"
"INDEX(ActCod)," "INDEX(ActCod),"
"INDEX(CtyCod)," "INDEX(CtyCod),"
@ -2463,7 +2463,7 @@ mysql> DESCRIBE plg_plugins;
"Logo VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_LOGO "Logo VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_LOGO
"AppKey VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_APP_KEY "AppKey VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_APP_KEY
"URL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW "URL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"UNIQUE INDEX(PlgCod))"); "UNIQUE INDEX(PlgCod))");
/***** Table prg_clipboards *****/ /***** Table prg_clipboards *****/
@ -2880,7 +2880,7 @@ mysql> DESCRIBE set_ip_settings;
10 rows in set (0,01 sec) 10 rows in set (0,01 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS set_ip_settings (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS set_ip_settings ("
"IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "IP CHAR(15) NOT NULL," // Par_MAX_BYTES_IP
"UsrCod INT NOT NULL DEFAULT -1," "UsrCod INT NOT NULL DEFAULT -1,"
"LastChange DATETIME NOT NULL," "LastChange DATETIME NOT NULL,"
"FirstDayOfWeek TINYINT NOT NULL DEFAULT 0," "FirstDayOfWeek TINYINT NOT NULL DEFAULT 0,"

View File

@ -553,6 +553,8 @@ void Err_NoPermissionExit (void)
void Err_ShowErrorAndExit (const char *Txt) void Err_ShowErrorAndExit (const char *Txt)
{ {
FILE *FileOut;
/***** Unlock tables if locked *****/ /***** Unlock tables if locked *****/
DB_UnlockTables (); DB_UnlockTables ();
@ -587,11 +589,13 @@ void Err_ShowErrorAndExit (const char *Txt)
else else
{ {
/***** Send page. /***** Send page.
The HTML output is now in Gbl.F.Out file ==> The HTML output is now in output file ==>
==> copy it to standard output *****/ ==> copy it to standard output *****/
rewind (Gbl.F.Out); FileOut = Fil_GetOutputFile ();
Fil_FastCopyOfOpenFiles (Gbl.F.Out,stdout); rewind (FileOut);
Fil_FastCopyOfOpenFiles (FileOut,stdout);
Fil_CloseAndRemoveFileForHTMLOutput (); Fil_CloseAndRemoveFileForHTMLOutput ();
// Now output file is stdout
if (!Gbl.Action.IsAJAXAutoRefresh) if (!Gbl.Action.IsAJAXAutoRefresh)
{ {
@ -611,7 +615,6 @@ void Err_ShowErrorAndExit (const char *Txt)
/***** End the output *****/ /***** End the output *****/
if (!Gbl.Layout.HTMLEndWritten) if (!Gbl.Layout.HTMLEndWritten)
{ {
// Here Gbl.F.Out is stdout
if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB) if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
Lay_WriteAboutZone (); Lay_WriteAboutZone ();

View File

@ -36,6 +36,7 @@
#include "swad_exam_print.h" #include "swad_exam_print.h"
#include "swad_exam_set.h" #include "swad_exam_set.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
@ -2158,8 +2159,8 @@ void Exa_DB_LogAccess (long LogCod,long PrnCod,ExaLog_Action_t Action)
ExaLog_GetQstInd (), ExaLog_GetQstInd (),
ExaLog_GetIfCanAnswer () ? 'Y' : ExaLog_GetIfCanAnswer () ? 'Y' :
'N', 'N',
// NOW() Redundant, for speed // NOW() Redundant, for speed
Gbl.IP); // Redundant, for speed Par_GetIP ()); // Redundant, for speed
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -37,6 +37,7 @@
#include "swad_exam_database.h" #include "swad_exam_database.h"
#include "swad_exam_log.h" #include "swad_exam_log.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
@ -234,7 +235,7 @@ void ExaLog_ShowExamLog (const struct ExaPrn_Print *Print)
int QstInd; int QstInd;
bool UsrCouldAnswer; bool UsrCouldAnswer;
time_t ClickTimeUTC; time_t ClickTimeUTC;
char IP[Cns_MAX_BYTES_IP + 1]; char IP[Par_MAX_BYTES_IP + 1];
char *Id; char *Id;
size_t Length; size_t Length;
char Anonymized[14 + 1]; // ***&hellip;*** char Anonymized[14 + 1]; // ***&hellip;***

View File

@ -56,7 +56,7 @@ extern struct Globals Gbl;
/***************************** Private constants *****************************/ /***************************** Private constants *****************************/
/*****************************************************************************/ /*****************************************************************************/
#define NUM_BYTES_PER_CHUNK 4096 #define Fil_NUM_BYTES_PER_CHUNK 4096
static struct static struct
{ {
@ -68,6 +68,7 @@ static struct
/*****************************************************************************/ /*****************************************************************************/
static FILE *Fil_QueryFile = NULL; // Temporary file to save stdin static FILE *Fil_QueryFile = NULL; // Temporary file to save stdin
static FILE *Fil_Out = NULL; // Temporary file to save output to be written to stdout
/*****************************************************************************/ /*****************************************************************************/
/***************************** Get query file ********************************/ /***************************** Get query file ********************************/
@ -78,6 +79,20 @@ FILE *Fil_GetQueryFile (void)
return Fil_QueryFile; return Fil_QueryFile;
} }
/*****************************************************************************/
/*************************** Set/Get output file *****************************/
/*****************************************************************************/
void Fil_SetOutputFileToStdout (void)
{
Fil_Out = stdout;
}
FILE *Fil_GetOutputFile (void)
{
return Fil_Out;
}
/*****************************************************************************/ /*****************************************************************************/
/******** Create HTML output file for the web page sent by this CGI **********/ /******** Create HTML output file for the web page sent by this CGI **********/
/*****************************************************************************/ /*****************************************************************************/
@ -92,9 +107,9 @@ void Fil_CreateFileForHTMLOutput (void)
"%s/%s.html",Cfg_PATH_OUT_PRIVATE,Cry_GetUniqueNameEncrypted ()); "%s/%s.html",Cfg_PATH_OUT_PRIVATE,Cry_GetUniqueNameEncrypted ());
/***** Open file for writing and reading *****/ /***** Open file for writing and reading *****/
if ((Gbl.F.Out = fopen (Fil_HTMLOutput.FileName,"w+t")) == NULL) if ((Fil_Out = fopen (Fil_HTMLOutput.FileName,"w+t")) == NULL)
{ {
Gbl.F.Out = stdout; Fil_SetOutputFileToStdout ();
Err_ShowErrorAndExit ("Can not create output file."); Err_ShowErrorAndExit ("Can not create output file.");
} }
} }
@ -105,12 +120,12 @@ void Fil_CreateFileForHTMLOutput (void)
void Fil_CloseAndRemoveFileForHTMLOutput (void) void Fil_CloseAndRemoveFileForHTMLOutput (void)
{ {
if (Gbl.F.Out) if (Fil_Out)
{ {
fclose (Gbl.F.Out); fclose (Fil_Out);
unlink (Fil_HTMLOutput.FileName); unlink (Fil_HTMLOutput.FileName);
} }
Gbl.F.Out = stdout; Fil_SetOutputFileToStdout ();
} }
/*****************************************************************************/ /*****************************************************************************/
@ -277,7 +292,7 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile,
bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param) bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param)
{ {
FILE *FileDataTmp; FILE *FileDataTmp;
unsigned char Bytes[NUM_BYTES_PER_CHUNK]; unsigned char Bytes[Fil_NUM_BYTES_PER_CHUNK];
size_t RemainingBytesToCopy; size_t RemainingBytesToCopy;
size_t BytesToCopy; size_t BytesToCopy;
FILE *QueryFile = Fil_GetQueryFile (); FILE *QueryFile = Fil_GetQueryFile ();
@ -297,8 +312,8 @@ bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param)
RemainingBytesToCopy != 0; RemainingBytesToCopy != 0;
RemainingBytesToCopy -= BytesToCopy) RemainingBytesToCopy -= BytesToCopy)
{ {
BytesToCopy = (RemainingBytesToCopy >= NUM_BYTES_PER_CHUNK) ? NUM_BYTES_PER_CHUNK : BytesToCopy = (RemainingBytesToCopy >= Fil_NUM_BYTES_PER_CHUNK) ? Fil_NUM_BYTES_PER_CHUNK :
RemainingBytesToCopy; RemainingBytesToCopy;
if (fread (Bytes,1,BytesToCopy,QueryFile) != BytesToCopy) if (fread (Bytes,1,BytesToCopy,QueryFile) != BytesToCopy)
{ {
fclose (FileDataTmp); fclose (FileDataTmp);
@ -567,26 +582,14 @@ void Fil_FastCopyOfFiles (const char *PathSrc,const char *PathTgt)
void Fil_FastCopyOfOpenFiles (FILE *FileSrc,FILE *FileTgt) void Fil_FastCopyOfOpenFiles (FILE *FileSrc,FILE *FileTgt)
{ {
unsigned char Bytes[NUM_BYTES_PER_CHUNK]; unsigned char Bytes[Fil_NUM_BYTES_PER_CHUNK];
size_t NumBytesRead; size_t NumBytesRead;
while ((NumBytesRead = fread (Bytes,sizeof (Bytes[0]),(size_t) NUM_BYTES_PER_CHUNK,FileSrc))) while ((NumBytesRead = fread (Bytes,sizeof (Bytes[0]),
(size_t) Fil_NUM_BYTES_PER_CHUNK,FileSrc)))
fwrite (Bytes,sizeof (Bytes[0]),NumBytesRead,FileTgt); fwrite (Bytes,sizeof (Bytes[0]),NumBytesRead,FileTgt);
} }
/*****************************************************************************/
/***************************** Close report file *****************************/
/*****************************************************************************/
void Fil_CloseReportFile (void)
{
if (Gbl.F.Rep)
{
fclose (Gbl.F.Rep);
Gbl.F.Rep = NULL; // To indicate that it is not open
}
}
/*****************************************************************************/ /*****************************************************************************/
/********** Write a quantity of bytes as bytes, KiB, MiB, GiB or TiB *********/ /********** Write a quantity of bytes as bytes, KiB, MiB, GiB or TiB *********/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -44,13 +44,6 @@
// Must be < 2 GiB, because off_t type is of type long int // Must be < 2 GiB, because off_t type is of type long int
#define Fil_MAX_FILE_SIZE (2000ULL * 1024ULL * 1024ULL) // 2000 MiB = 1.95 GiB #define Fil_MAX_FILE_SIZE (2000ULL * 1024ULL * 1024ULL) // 2000 MiB = 1.95 GiB
// Global files
struct Fil_Files
{
FILE *Out; // File with the HTML output of this CGI
FILE *Rep; // Temporary file to save report
};
#define Fil_MAX_BYTES_FILE_SIZE_STRING (32 - 1) #define Fil_MAX_BYTES_FILE_SIZE_STRING (32 - 1)
/*****************************************************************************/ /*****************************************************************************/
@ -58,6 +51,9 @@ struct Fil_Files
/*****************************************************************************/ /*****************************************************************************/
FILE *Fil_GetQueryFile (void); FILE *Fil_GetQueryFile (void);
void Fil_SetOutputFileToStdout (void);
FILE *Fil_GetOutputFile (void);
void Fil_CreateFileForHTMLOutput (void); void Fil_CreateFileForHTMLOutput (void);
void Fil_CloseAndRemoveFileForHTMLOutput (void); void Fil_CloseAndRemoveFileForHTMLOutput (void);
bool Fil_ReadStdinIntoTmpFile (void); bool Fil_ReadStdinIntoTmpFile (void);
@ -84,8 +80,6 @@ void Fil_RemoveOldTmpFiles (const char *Path,time_t TimeToRemove,
void Fil_FastCopyOfFiles (const char *PathSrc,const char *PathTgt); void Fil_FastCopyOfFiles (const char *PathSrc,const char *PathTgt);
void Fil_FastCopyOfOpenFiles (FILE *FileSrc,FILE *FileTgt); void Fil_FastCopyOfOpenFiles (FILE *FileSrc,FILE *FileTgt);
void Fil_CloseReportFile (void);
void Fil_WriteFileSizeBrief (double SizeInBytes, void Fil_WriteFileSizeBrief (double SizeInBytes,
char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]); char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]);
void Fil_WriteFileSizeFull (double SizeInBytes, void Fil_WriteFileSizeFull (double SizeInBytes,

View File

@ -30,6 +30,7 @@
#include "swad_database.h" #include "swad_database.h"
#include "swad_firewall.h" #include "swad_firewall.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
@ -48,7 +49,7 @@ void Fir_DB_LogAccess (void)
" (ClickTime,IP)" " (ClickTime,IP)"
" VALUES" " VALUES"
" (NOW(),'%s')", " (NOW(),'%s')",
Gbl.IP); Par_GetIP ());
} }
/*****************************************************************************/ /*****************************************************************************/
@ -63,7 +64,7 @@ unsigned Fir_DB_GetNumClicksFromLog (void)
" FROM fir_log" " FROM fir_log"
" WHERE IP='%s'" " WHERE IP='%s'"
" AND ClickTime>FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)", " AND ClickTime>FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
Gbl.IP, Par_GetIP (),
Fw_CHECK_INTERVAL); Fw_CHECK_INTERVAL);
} }
@ -90,7 +91,7 @@ void Fir_DB_BanIP (void)
" (IP,BanTime,UnbanTime)" " (IP,BanTime,UnbanTime)"
" VALUES" " VALUES"
" ('%s',NOW(),FROM_UNIXTIME(UNIX_TIMESTAMP()+%lu))", " ('%s',NOW(),FROM_UNIXTIME(UNIX_TIMESTAMP()+%lu))",
Gbl.IP, Par_GetIP (),
(unsigned long) Fw_TIME_BANNED); (unsigned long) Fw_TIME_BANNED);
} }
@ -106,5 +107,5 @@ unsigned Fir_DB_GetNumBansIP (void)
" FROM fir_banned" " FROM fir_banned"
" WHERE IP='%s'" " WHERE IP='%s'"
" AND UnbanTime>NOW()", " AND UnbanTime>NOW()",
Gbl.IP); Par_GetIP ());
} }

View File

@ -49,6 +49,7 @@
#include "swad_link.h" #include "swad_link.h"
#include "swad_parameter.h" #include "swad_parameter.h"
#include "swad_plugin.h" #include "swad_plugin.h"
#include "swad_process.h"
#include "swad_program.h" #include "swad_program.h"
#include "swad_project.h" #include "swad_project.h"
#include "swad_role.h" #include "swad_role.h"
@ -85,8 +86,8 @@ void Gbl_InitializeGlobals (void)
Dat_SetStartExecutionTimeUTC (); Dat_SetStartExecutionTimeUTC ();
Dat_GetAndConvertCurrentDateTime (); Dat_GetAndConvertCurrentDateTime ();
Gbl.PID = getpid (); Prc_SetPID ();
Sta_GetRemoteAddr (); Par_SetIP ();
Cry_CreateUniqueNameEncrypted (Cry_GetUniqueNameEncrypted ()); Cry_CreateUniqueNameEncrypted (Cry_GetUniqueNameEncrypted ());
@ -94,8 +95,7 @@ void Gbl_InitializeGlobals (void)
Gbl.WebService.IsWebService = false; Gbl.WebService.IsWebService = false;
Gbl.F.Out = stdout; Fil_SetOutputFileToStdout ();
Gbl.F.Rep = NULL; // Report
Gbl.Prefs.Language = Txt_Current_CGI_SWAD_Language; Gbl.Prefs.Language = Txt_Current_CGI_SWAD_Language;
Gbl.Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week Gbl.Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week
@ -336,7 +336,6 @@ void Gbl_Cleanup (void)
Usr_FreeListOtherRecipients (); Usr_FreeListOtherRecipients ();
Usr_FreeListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected); Usr_FreeListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected);
Syl_FreeListItemsSyllabus (); Syl_FreeListItemsSyllabus ();
Fil_CloseReportFile ();
Par_FreeParams (); Par_FreeParams ();
Ale_ResetAllAlerts (); Ale_ResetAllAlerts ();
} }

View File

@ -50,9 +50,6 @@
struct Globals struct Globals
{ {
struct Fil_Files F;
pid_t PID; // PID of current process
char IP[Cns_MAX_BYTES_IP + 1];
struct struct
{ {
bool WritingHTMLStart; // Used to avoid writing the HTML head when aborting program on error bool WritingHTMLStart; // Used to avoid writing the HTML head when aborting program on error

View File

@ -1636,7 +1636,7 @@ static bool Inf_CheckAndShowRichTxt (void)
Err_ShowErrorAndExit ("Can not open temporary HTML file."); Err_ShowErrorAndExit ("Can not open temporary HTML file.");
/* Copy from temporary HTML file to output file */ /* Copy from temporary HTML file to output file */
Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out); Fil_FastCopyOfOpenFiles (FileHTML,Fil_GetOutputFile ());
/* Close and remove temporary HTML file */ /* Close and remove temporary HTML file */
fclose (FileHTML); fclose (FileHTML);

View File

@ -63,6 +63,7 @@
#include "swad_notice.h" #include "swad_notice.h"
#include "swad_notification.h" #include "swad_notification.h"
#include "swad_parameter.h" #include "swad_parameter.h"
#include "swad_process.h"
#include "swad_setting.h" #include "swad_setting.h"
#include "swad_setting_database.h" #include "swad_setting_database.h"
#include "swad_tab.h" #include "swad_tab.h"
@ -1363,42 +1364,43 @@ void Lay_RefreshNotifsAndConnected (void)
unsigned NumUsr; unsigned NumUsr;
bool ShowConnected = (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) && bool ShowConnected = (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) &&
Gbl.Hierarchy.Level == HieLvl_CRS; // Right column visible && There is a course selected Gbl.Hierarchy.Level == HieLvl_CRS; // Right column visible && There is a course selected
pid_t PID = Prc_GetPID ();
/***** Sometimes, someone must do this work, /***** Sometimes, someone must do this work,
so who best than processes that refresh via AJAX? *****/ so who best than processes that refresh via AJAX? *****/
// We use (PID % prime-number) to do only one action as much // We use (PID % prime-number) to do only one action as much
if (!(Gbl.PID % 11)) if (!(PID % 11))
Ntf_SendPendingNotifByEMailToAllUsrs (); // Send pending notifications by email Ntf_SendPendingNotifByEMailToAllUsrs (); // Send pending notifications by email
else if (!(Gbl.PID % 19)) else if (!(PID % 19))
Fir_DB_PurgeFirewallLog (); // Remove old clicks from firewall Fir_DB_PurgeFirewallLog (); // Remove old clicks from firewall
else if (!(Gbl.PID % 23)) else if (!(PID % 23))
Fil_RemoveOldTmpFiles (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, Fil_RemoveOldTmpFiles (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC,
Cfg_TIME_TO_DELETE_BROWSER_TMP_FILES,false); // Remove the oldest temporary public directories used for downloading Cfg_TIME_TO_DELETE_BROWSER_TMP_FILES,false); // Remove the oldest temporary public directories used for downloading
else if (!(Gbl.PID % 101)) else if (!(PID % 101))
Brw_DB_RemoveExpiredExpandedFolders (); // Remove old expanded folders (from all users) Brw_DB_RemoveExpiredExpandedFolders (); // Remove old expanded folders (from all users)
else if (!(Gbl.PID % 103)) else if (!(PID % 103))
Set_DB_RemoveOldSettingsFromIP (); // Remove old settings from IP Set_DB_RemoveOldSettingsFromIP (); // Remove old settings from IP
else if (!(Gbl.PID % 107)) else if (!(PID % 107))
Log_DB_RemoveOldEntriesRecentLog (); // Remove old entries in recent log table, it's a slow query Log_DB_RemoveOldEntriesRecentLog (); // Remove old entries in recent log table, it's a slow query
else if (!(Gbl.PID % 109)) else if (!(PID % 109))
Fil_RemoveOldTmpFiles (Cfg_PATH_OUT_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_OUT_PRIVATE,
Cfg_TIME_TO_DELETE_HTML_OUTPUT ,false); Cfg_TIME_TO_DELETE_HTML_OUTPUT ,false);
else if (!(Gbl.PID % 113)) else if (!(PID % 113))
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PUBLIC, Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PUBLIC,
Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false); Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
else if (!(Gbl.PID % 127)) else if (!(PID % 127))
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PRIVATE,
Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false); Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
else if (!(Gbl.PID % 131)) else if (!(PID % 131))
Fil_RemoveOldTmpFiles (Cfg_PATH_MEDIA_TMP_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_MEDIA_TMP_PRIVATE,
Cfg_TIME_TO_DELETE_MEDIA_TMP_FILES ,false); Cfg_TIME_TO_DELETE_MEDIA_TMP_FILES ,false);
else if (!(Gbl.PID % 137)) else if (!(PID % 137))
Fil_RemoveOldTmpFiles (Cfg_PATH_ZIP_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_ZIP_PRIVATE,
Cfg_TIME_TO_DELETE_BROWSER_ZIP_FILES,false); Cfg_TIME_TO_DELETE_BROWSER_ZIP_FILES,false);
else if (!(Gbl.PID % 139)) else if (!(PID % 139))
Fil_RemoveOldTmpFiles (Cfg_PATH_MARK_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_MARK_PRIVATE,
Cfg_TIME_TO_DELETE_MARKS_TMP_FILES ,false); Cfg_TIME_TO_DELETE_MARKS_TMP_FILES ,false);
else if (!(Gbl.PID % 149)) else if (!(PID % 149))
Fil_RemoveOldTmpFiles (Cfg_PATH_TEST_PRIVATE, Fil_RemoveOldTmpFiles (Cfg_PATH_TEST_PRIVATE,
Cfg_TIME_TO_DELETE_TEST_TMP_FILES ,false); Cfg_TIME_TO_DELETE_TEST_TMP_FILES ,false);
@ -1455,7 +1457,7 @@ static void Lay_WriteFootFromHTMLFile (void)
HTM_Txt ("<footer id=\"foot_zone\">"); HTM_Txt ("<footer id=\"foot_zone\">");
/***** Copy HTML to output file *****/ /***** Copy HTML to output file *****/
Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out); Fil_FastCopyOfOpenFiles (FileHTML,Fil_GetOutputFile ());
fclose (FileHTML); fclose (FileHTML);
HTM_Txt ("</footer>"); HTM_Txt ("</footer>");

View File

@ -29,6 +29,7 @@
#include "swad_database.h" #include "swad_database.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_log.h" #include "swad_log.h"
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
@ -62,7 +63,7 @@ long Log_DB_LogAccessInHistoricalLog (long ActCod,Rol_Role_t RoleToStore)
(unsigned) RoleToStore, (unsigned) RoleToStore,
Dat_GetTimeGenerationInMicroseconds (), Dat_GetTimeGenerationInMicroseconds (),
Dat_GetTimeSendInMicroseconds (), Dat_GetTimeSendInMicroseconds (),
Gbl.IP); Par_GetIP ());
} }
/*****************************************************************************/ /*****************************************************************************/
@ -91,7 +92,7 @@ void Log_DB_LogAccessInRecentLog (long LogCod,long ActCod,Rol_Role_t RoleToStore
(unsigned) RoleToStore, (unsigned) RoleToStore,
Dat_GetTimeGenerationInMicroseconds (), Dat_GetTimeGenerationInMicroseconds (),
Dat_GetTimeSendInMicroseconds (), Dat_GetTimeSendInMicroseconds (),
Gbl.IP); Par_GetIP ());
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -609,7 +609,7 @@ void Mrk_ShowMyMarks (void)
Gbl.Layout.HTMLStartWritten = true; Gbl.Layout.HTMLStartWritten = true;
/* Copy HTML to output file */ /* Copy HTML to output file */
Fil_FastCopyOfOpenFiles (FileUsrMarks,Gbl.F.Out); Fil_FastCopyOfOpenFiles (FileUsrMarks,Fil_GetOutputFile ());
fclose (FileUsrMarks); fclose (FileUsrMarks);
Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true; Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true;

View File

@ -2724,7 +2724,7 @@ void Msg_WriteMsgContent (char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
/***** Write message to file *****/ /***** Write message to file *****/
if (ChangeBRToRet) if (ChangeBRToRet)
Str_FilePrintStrChangingBRToRetAndNBSPToSpace (Gbl.F.Out,Content); Str_FilePrintStrChangingBRToRetAndNBSPToSpace (Fil_GetOutputFile (),Content);
else else
HTM_Txt (Content); HTM_Txt (Content);
} }

View File

@ -83,6 +83,7 @@ static struct
size_t LengthWithoutCRLF; size_t LengthWithoutCRLF;
size_t LengthWithCRLF; size_t LengthWithCRLF;
} Boundary; } Boundary;
char IP[Par_MAX_BYTES_IP + 1];
} Par_Params = } Par_Params =
{ {
.ContentReceivedByCGI = Act_CONT_NORM, .ContentReceivedByCGI = Act_CONT_NORM,
@ -1145,3 +1146,24 @@ void Par_PutHiddenParamString (const char *Id,const char *ParamName,
ParamName,Value ? Value : ParamName,Value ? Value :
""); "");
} }
/*****************************************************************************/
/****************************** Set/Get current IP ***************************/
/*****************************************************************************/
/*
CGI Environment Variables:
REMOTE_ADDR
The IP address of the remote host making the request.
*/
void Par_SetIP (void)
{
if (getenv ("REMOTE_ADDR"))
Str_Copy (Par_Params.IP,getenv ("REMOTE_ADDR"),sizeof (Par_Params.IP) - 1);
else
Par_Params.IP[0] = '\0';
}
const char *Par_GetIP (void)
{
return Par_Params.IP;
}

View File

@ -63,6 +63,12 @@ typedef enum
Par_PARAM_MULTIPLE, Par_PARAM_MULTIPLE,
} Par_ParamType_t; // Parameter is present only one time / multiple times } Par_ParamType_t; // Parameter is present only one time / multiple times
#define Par_MAX_CHARS_IP (3 + 1 + 3 + 1 + 3 + 1 + 3) // 15: max. number of chars of an IP address
// Example: 255.255.255.255
// 3+1+3+1+3+1+3
// 123456789012345
#define Par_MAX_BYTES_IP Par_MAX_CHARS_IP // 15
/*****************************************************************************/ /*****************************************************************************/
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -102,4 +108,8 @@ void Par_PutHiddenParamChar (const char *ParamName,char Value);
void Par_PutHiddenParamString (const char *Id,const char *ParamName, void Par_PutHiddenParamString (const char *Id,const char *ParamName,
const char *Value); const char *Value);
//----------------------------- Client IP address -----------------------------
void Par_SetIP (void);
const char *Par_GetIP (void);
#endif #endif

View File

@ -426,7 +426,7 @@ static void Plg_ListPluginsForEdition (void)
HTM_TD_Begin ("class=\"CM\""); HTM_TD_Begin ("class=\"CM\"");
Frm_BeginForm (ActChgPlgIP); Frm_BeginForm (ActChgPlgIP);
Plg_PutParamPlgCod (&Plg->PlgCod); Plg_PutParamPlgCod (&Plg->PlgCod);
HTM_INPUT_TEXT ("IP",Cns_MAX_CHARS_IP,Plg->IP,HTM_SUBMIT_ON_CHANGE, HTM_INPUT_TEXT ("IP",Par_MAX_CHARS_IP,Plg->IP,HTM_SUBMIT_ON_CHANGE,
"size=\"10\" class=\"INPUT_%s\"", "size=\"10\" class=\"INPUT_%s\"",
The_GetSuffix ()); The_GetSuffix ());
Frm_EndForm (); Frm_EndForm ();
@ -718,7 +718,7 @@ void Plg_ChangePlgURL (void)
void Plg_ChangePlgIP (void) void Plg_ChangePlgIP (void)
{ {
extern const char *Txt_The_new_IP_address_is_X; extern const char *Txt_The_new_IP_address_is_X;
char NewIP[Cns_MAX_BYTES_IP + 1]; char NewIP[Par_MAX_BYTES_IP + 1];
/***** Plugin constructor *****/ /***** Plugin constructor *****/
Plg_EditingPluginConstructor (); Plg_EditingPluginConstructor ();
@ -729,7 +729,7 @@ void Plg_ChangePlgIP (void)
Err_WrongPluginExit (); Err_WrongPluginExit ();
/* Get the new IP for the plugin */ /* Get the new IP for the plugin */
Par_GetParToText ("IP",NewIP,Cns_MAX_BYTES_IP); Par_GetParToText ("IP",NewIP,Par_MAX_BYTES_IP);
/***** Get plugin data from the database *****/ /***** Get plugin data from the database *****/
Plg_GetDataOfPluginByCod (Plg_EditingPlg); Plg_GetDataOfPluginByCod (Plg_EditingPlg);
@ -851,7 +851,7 @@ static void Plg_PutFormToCreatePlugin (void)
/***** Plugin IP address *****/ /***** Plugin IP address *****/
HTM_TD_Begin ("class=\"CM\""); HTM_TD_Begin ("class=\"CM\"");
HTM_INPUT_TEXT ("IP",Cns_MAX_CHARS_IP,Plg_EditingPlg->IP, HTM_INPUT_TEXT ("IP",Par_MAX_CHARS_IP,Plg_EditingPlg->IP,
HTM_DONT_SUBMIT_ON_CHANGE, HTM_DONT_SUBMIT_ON_CHANGE,
"size=\"10\" class=\"INPUT_%s\"" "size=\"10\" class=\"INPUT_%s\""
" required=\"required\"", " required=\"required\"",
@ -926,7 +926,7 @@ void Plg_ReceiveFormNewPlg (void)
Par_GetParToText ("URL",Plg_EditingPlg->URL,Cns_MAX_BYTES_WWW); Par_GetParToText ("URL",Plg_EditingPlg->URL,Cns_MAX_BYTES_WWW);
/* Get plugin IP address */ /* Get plugin IP address */
Par_GetParToText ("IP",Plg_EditingPlg->IP,Cns_MAX_BYTES_IP); Par_GetParToText ("IP",Plg_EditingPlg->IP,Par_MAX_BYTES_IP);
if (Plg_EditingPlg->Name[0]) // If there's a plugin name if (Plg_EditingPlg->Name[0]) // If there's a plugin name
{ {

View File

@ -23,6 +23,12 @@
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/****************************** Public constants *****************************/ /****************************** Public constants *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -51,7 +57,7 @@ struct Plg_Plugin
char Logo[Plg_MAX_BYTES_PLUGIN_LOGO + 1]; char Logo[Plg_MAX_BYTES_PLUGIN_LOGO + 1];
char AppKey[Plg_MAX_BYTES_PLUGIN_APP_KEY + 1]; char AppKey[Plg_MAX_BYTES_PLUGIN_APP_KEY + 1];
char URL[Cns_MAX_BYTES_WWW + 1]; char URL[Cns_MAX_BYTES_WWW + 1];
char IP[Cns_MAX_BYTES_IP + 1]; char IP[Par_MAX_BYTES_IP + 1];
}; };
/*****************************************************************************/ /*****************************************************************************/

View File

@ -127,7 +127,7 @@ void Plg_DB_ChangeURL (long PlgCod,
/*****************************************************************************/ /*****************************************************************************/
void Plg_DB_ChangeIP (long PlgCod, void Plg_DB_ChangeIP (long PlgCod,
const char NewIP[Cns_MAX_BYTES_IP + 1]) const char NewIP[Par_MAX_BYTES_IP + 1])
{ {
DB_QueryUPDATE ("can not update the IP address of a plugin", DB_QueryUPDATE ("can not update the IP address of a plugin",
"UPDATE plg_plugins" "UPDATE plg_plugins"

View File

@ -47,7 +47,7 @@ void Plg_DB_ChangeAppKey (long PlgCod,
void Plg_DB_ChangeURL (long PlgCod, void Plg_DB_ChangeURL (long PlgCod,
const char NewURL[Cns_MAX_BYTES_WWW + 1]); const char NewURL[Cns_MAX_BYTES_WWW + 1]);
void Plg_DB_ChangeIP (long PlgCod, void Plg_DB_ChangeIP (long PlgCod,
const char NewIP[Cns_MAX_BYTES_IP + 1]); const char NewIP[Par_MAX_BYTES_IP + 1]);
unsigned Plg_DB_GetListPlugins (MYSQL_RES **mysql_res); unsigned Plg_DB_GetListPlugins (MYSQL_RES **mysql_res);
unsigned Plg_DB_GetDataOfPluginByCod (MYSQL_RES **mysql_res,long PlgCod); unsigned Plg_DB_GetDataOfPluginByCod (MYSQL_RES **mysql_res,long PlgCod);

48
swad_process.c Normal file
View File

@ -0,0 +1,48 @@
// swad_process.c: process in which this program runs
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2022 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_process.h"
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
static pid_t Prc_PID; // PID of current process
/*****************************************************************************/
/************ Set/Get current PID (process identification number) ************/
/*****************************************************************************/
void Prc_SetPID (void)
{
Prc_PID = getpid ();
}
pid_t Prc_GetPID (void)
{
return Prc_PID;
}

39
swad_process.h Normal file
View File

@ -0,0 +1,39 @@
// swad_process.h: process in which this program runs
#ifndef _SWAD_PRC
#define _SWAD_PRC
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2022 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include <unistd.h> // For getpid
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void Prc_SetPID (void);
pid_t Prc_GetPID (void);
#endif

View File

@ -70,6 +70,12 @@
extern struct Globals Gbl; extern struct Globals Gbl;
/*****************************************************************************/
/************************* Private global variables **************************/
/*****************************************************************************/
static FILE *Rep_File;
/*****************************************************************************/ /*****************************************************************************/
/***************************** Private prototypes ****************************/ /***************************** Private prototypes ****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -176,10 +182,10 @@ static void Rep_CreateMyUsageReport (struct Rep_Report *Report)
Cry_GetUniqueNameEncrypted ()); Cry_GetUniqueNameEncrypted ());
/***** Begin file *****/ /***** Begin file *****/
Lay_BeginHTMLFile (Gbl.F.Rep,Report->FilenameReport); Lay_BeginHTMLFile (Rep_File,Report->FilenameReport);
fprintf (Gbl.F.Rep,"<body style=\"margin:1em;" fprintf (Rep_File,"<body style=\"margin:1em;"
" text-align:left;" " text-align:left;"
" font-family:Helvetica,Arial,sans-serif;\">\n"); " font-family:Helvetica,Arial,sans-serif;\">\n");
/***** Header *****/ /***** Header *****/
Rep_WriteHeader (Report); Rep_WriteHeader (Report);
@ -215,11 +221,11 @@ static void Rep_CreateMyUsageReport (struct Rep_Report *Report)
Rep_WriteSectionHistoricCourses (Report); Rep_WriteSectionHistoricCourses (Report);
/***** End file *****/ /***** End file *****/
fprintf (Gbl.F.Rep,"</body>\n" fprintf (Rep_File,"</body>\n"
"</html>\n"); "</html>\n");
/***** Close report file *****/ /***** Close report file *****/
Fil_CloseReportFile (); fclose (Rep_File);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -373,7 +379,7 @@ static void Rep_CreateNewReportFile (struct Rep_Report *Report)
Rep_FILENAME_ROOT,Report->CurrentTimeUTC.Date,Report->CurrentTimeUTC.Time); Rep_FILENAME_ROOT,Report->CurrentTimeUTC.Date,Report->CurrentTimeUTC.Time);
snprintf (PathFileReport,sizeof (PathFileReport),"%s/%s", snprintf (PathFileReport,sizeof (PathFileReport),"%s/%s",
PathUniqueDirR,Report->FilenameReport); PathUniqueDirR,Report->FilenameReport);
if ((Gbl.F.Rep = fopen (PathFileReport,"wb")) == NULL) if ((Rep_File = fopen (PathFileReport,"wb")) == NULL)
Err_ShowErrorAndExit ("Can not create report file."); Err_ShowErrorAndExit ("Can not create report file.");
/***** Permalink *****/ /***** Permalink *****/
@ -398,36 +404,36 @@ static void Rep_WriteHeader (const struct Rep_Report *Report)
extern const char *Txt_Permalink; extern const char *Txt_Permalink;
/***** Begin header *****/ /***** Begin header *****/
fprintf (Gbl.F.Rep,"<header>" fprintf (Rep_File,"<header>"
"<h1>"); "<h1>");
fprintf (Gbl.F.Rep,Txt_Report_of_use_of_PLATFORM,Cfg_PLATFORM_SHORT_NAME); fprintf (Rep_File,Txt_Report_of_use_of_PLATFORM,Cfg_PLATFORM_SHORT_NAME);
fprintf (Gbl.F.Rep,"</h1>" fprintf (Rep_File,"</h1>"
"<ul>"); "<ul>");
/***** User *****/ /***** User *****/
fprintf (Gbl.F.Rep,"<li>%s: <strong>%s</strong></li>", fprintf (Rep_File,"<li>%s: <strong>%s</strong></li>",
Txt_User[Gbl.Usrs.Me.UsrDat.Sex], Txt_User[Gbl.Usrs.Me.UsrDat.Sex],
Gbl.Usrs.Me.UsrDat.FullName); Gbl.Usrs.Me.UsrDat.FullName);
/***** Date-time *****/ /***** Date-time *****/
fprintf (Gbl.F.Rep,"<li>%s: %s %s UTC</li>", fprintf (Rep_File,"<li>%s: %s %s UTC</li>",
Txt_Date, Txt_Date,
Report->CurrentTimeUTC.StrDate, Report->CurrentTimeUTC.StrDate,
Report->CurrentTimeUTC.StrTime); Report->CurrentTimeUTC.StrTime);
/***** Permalink *****/ /***** Permalink *****/
fprintf (Gbl.F.Rep,"<li>%s: " fprintf (Rep_File,"<li>%s: "
"<a href=\"%s\" target=\"_blank\"" "<a href=\"%s\" target=\"_blank\""
" style=\"text-decoration:none;\">" " style=\"text-decoration:none;\">"
"%s" "%s"
"</a>" "</a>"
"</li>", "</li>",
Txt_Permalink, Txt_Permalink,
Report->Permalink,Report->Permalink); Report->Permalink,Report->Permalink);
/***** End header *****/ /***** End header *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</header>\n"); "</header>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -442,28 +448,28 @@ static void Rep_WriteSectionPlatform (void)
extern const char *Txt_URL; extern const char *Txt_URL;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s</h3>", "<h3>%s</h3>",
Txt_Teaching_platform); Txt_Teaching_platform);
fprintf (Gbl.F.Rep,"<ul>"); fprintf (Rep_File,"<ul>");
/***** Platform name *****/ /***** Platform name *****/
fprintf (Gbl.F.Rep,"<li>%s: %s, %s</li>", fprintf (Rep_File,"<li>%s: %s, %s</li>",
Txt_Name, Txt_Name,
Cfg_PLATFORM_FULL_NAME,Txt_TAGLINE); Cfg_PLATFORM_FULL_NAME,Txt_TAGLINE);
/***** Server URL *****/ /***** Server URL *****/
fprintf (Gbl.F.Rep,"<li>%s: " fprintf (Rep_File,"<li>%s: "
"<a href=\"%s\" target=\"_blank\"" "<a href=\"%s\" target=\"_blank\""
" style=\"text-decoration:none;\">" " style=\"text-decoration:none;\">"
"%s" "%s"
"</a>" "</a>"
"</li>", "</li>",
Txt_URL,Cfg_URL_SWAD_SERVER,Cfg_URL_SWAD_SERVER); Txt_URL,Cfg_URL_SWAD_SERVER,Cfg_URL_SWAD_SERVER);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</section>\n"); "</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -481,37 +487,37 @@ static void Rep_WriteSectionUsrInfo (void)
struct Ins_Instit Ins; struct Ins_Instit Ins;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s</h3>", "<h3>%s</h3>",
Txt_Personal_information); Txt_Personal_information);
fprintf (Gbl.F.Rep,"<ul>"); fprintf (Rep_File,"<ul>");
/***** User's name *****/ /***** User's name *****/
fprintf (Gbl.F.Rep,"<li>%s: %s</li>", fprintf (Rep_File,"<li>%s: %s</li>",
Txt_Name, Txt_Name,
Gbl.Usrs.Me.UsrDat.FullName); Gbl.Usrs.Me.UsrDat.FullName);
/***** User's email *****/ /***** User's email *****/
fprintf (Gbl.F.Rep,"<li>%s: %s</li>", fprintf (Rep_File,"<li>%s: %s</li>",
Txt_Email, Txt_Email,
Gbl.Usrs.Me.UsrDat.Email); Gbl.Usrs.Me.UsrDat.Email);
/***** User's country *****/ /***** User's country *****/
Cty_GetCountryName (Gbl.Usrs.Me.UsrDat.CtyCod,Gbl.Prefs.Language,CtyName); Cty_GetCountryName (Gbl.Usrs.Me.UsrDat.CtyCod,Gbl.Prefs.Language,CtyName);
fprintf (Gbl.F.Rep,"<li>%s: %s</li>", fprintf (Rep_File,"<li>%s: %s</li>",
Txt_Country, Txt_Country,
CtyName); CtyName);
/***** User's institution *****/ /***** User's institution *****/
Ins.InsCod = Gbl.Usrs.Me.UsrDat.InsCod; Ins.InsCod = Gbl.Usrs.Me.UsrDat.InsCod;
Ins_GetDataOfInstitByCod (&Ins); Ins_GetDataOfInstitByCod (&Ins);
fprintf (Gbl.F.Rep,"<li>%s: %s</li>", fprintf (Rep_File,"<li>%s: %s</li>",
Txt_Institution, Txt_Institution,
Ins.FullName); Ins.FullName);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</section>\n"); "</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -543,16 +549,16 @@ static void Rep_WriteSectionUsrFigures (const struct Rep_Report *Report)
unsigned NumPublicFiles; unsigned NumPublicFiles;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s</h3>", "<h3>%s</h3>",
Txt_Figures); Txt_Figures);
fprintf (Gbl.F.Rep,"<ul>"); fprintf (Rep_File,"<ul>");
/***** Time since first click until now *****/ /***** Time since first click until now *****/
fprintf (Gbl.F.Rep,"<li>%s ",Txt_TIME_Since); fprintf (Rep_File,"<li>%s ",Txt_TIME_Since);
if (Report->UsrFigures.FirstClickTimeUTC) if (Report->UsrFigures.FirstClickTimeUTC)
{ {
fprintf (Gbl.F.Rep,"%04d-%02d-%02d %02d:%02d:%02d UTC", fprintf (Rep_File,"%04d-%02d-%02d %02d:%02d:%02d UTC",
1900 + Report->tm_FirstClickTime.tm_year, // year 1900 + Report->tm_FirstClickTime.tm_year, // year
1 + Report->tm_FirstClickTime.tm_mon, // month 1 + Report->tm_FirstClickTime.tm_mon, // month
Report->tm_FirstClickTime.tm_mday, // day of the month Report->tm_FirstClickTime.tm_mday, // day of the month
@ -560,51 +566,51 @@ static void Rep_WriteSectionUsrFigures (const struct Rep_Report *Report)
Report->tm_FirstClickTime.tm_min, // minutes Report->tm_FirstClickTime.tm_min, // minutes
Report->tm_FirstClickTime.tm_sec); // seconds Report->tm_FirstClickTime.tm_sec); // seconds
if (Report->CurrentTimeUTC.StrDate[0]) if (Report->CurrentTimeUTC.StrDate[0])
fprintf (Gbl.F.Rep," %s %s %s UTC", fprintf (Rep_File," %s %s %s UTC",
Txt_TIME_until, Txt_TIME_until,
Report->CurrentTimeUTC.StrDate, Report->CurrentTimeUTC.StrDate,
Report->CurrentTimeUTC.StrTime); Report->CurrentTimeUTC.StrTime);
if (Report->UsrFigures.NumDays > 0) if (Report->UsrFigures.NumDays > 0)
fprintf (Gbl.F.Rep," (%d %s)", fprintf (Rep_File," (%d %s)",
Report->UsrFigures.NumDays, Report->UsrFigures.NumDays,
(Report->UsrFigures.NumDays == 1) ? Txt_day : (Report->UsrFigures.NumDays == 1) ? Txt_day :
Txt_days); Txt_days);
} }
else // Time of first click is unknown else // Time of first click is unknown
{ {
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
if (Report->CurrentTimeUTC.StrDate[0]) if (Report->CurrentTimeUTC.StrDate[0])
fprintf (Gbl.F.Rep," - %s %s UTC", fprintf (Rep_File," - %s %s UTC",
Report->CurrentTimeUTC.StrDate, Report->CurrentTimeUTC.StrDate,
Report->CurrentTimeUTC.StrTime); Report->CurrentTimeUTC.StrTime);
} }
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
/***** Number of clicks *****/ /***** Number of clicks *****/
fprintf (Gbl.F.Rep,"<li>%s: ",Txt_Clicks); fprintf (Rep_File,"<li>%s: ",Txt_Clicks);
if (Report->UsrFigures.NumClicks >= 0) if (Report->UsrFigures.NumClicks >= 0)
{ {
fprintf (Gbl.F.Rep,"%d",Report->UsrFigures.NumClicks); fprintf (Rep_File,"%d",Report->UsrFigures.NumClicks);
if (Report->UsrFigures.NumDays > 0) if (Report->UsrFigures.NumDays > 0)
{ {
fprintf (Gbl.F.Rep," ("); fprintf (Rep_File," (");
Rep_WriteDouble ((double) Report->UsrFigures.NumClicks / Rep_WriteDouble ((double) Report->UsrFigures.NumClicks /
(double) Report->UsrFigures.NumDays); (double) Report->UsrFigures.NumDays);
fprintf (Gbl.F.Rep," / %s)",Txt_day); fprintf (Rep_File," / %s)",Txt_day);
} }
} }
else // Number of clicks is unknown else // Number of clicks is unknown
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
/***** Number of files currently published *****/ /***** Number of files currently published *****/
if ((NumFiles = Brw_DB_GetNumFilesUsr (Gbl.Usrs.Me.UsrDat.UsrCod))) if ((NumFiles = Brw_DB_GetNumFilesUsr (Gbl.Usrs.Me.UsrDat.UsrCod)))
NumPublicFiles = Brw_DB_GetNumPublicFilesUsr (Gbl.Usrs.Me.UsrDat.UsrCod); NumPublicFiles = Brw_DB_GetNumPublicFilesUsr (Gbl.Usrs.Me.UsrDat.UsrCod);
else else
NumPublicFiles = 0; NumPublicFiles = 0;
fprintf (Gbl.F.Rep,"<li>" fprintf (Rep_File,"<li>"
"%s: %u %s (%u %s)" "%s: %u %s (%u %s)"
"</li>", "</li>",
Txt_Files_uploaded, Txt_Files_uploaded,
NumFiles, NumFiles,
(NumFiles == 1) ? Txt_file : (NumFiles == 1) ? Txt_file :
@ -612,68 +618,68 @@ static void Rep_WriteSectionUsrFigures (const struct Rep_Report *Report)
NumPublicFiles,Txt_public_FILES); NumPublicFiles,Txt_public_FILES);
/***** Number of file views *****/ /***** Number of file views *****/
fprintf (Gbl.F.Rep,"<li>%s: ",Txt_Downloads); fprintf (Rep_File,"<li>%s: ",Txt_Downloads);
if (Report->UsrFigures.NumFileViews >= 0) if (Report->UsrFigures.NumFileViews >= 0)
{ {
fprintf (Gbl.F.Rep,"%d %s", fprintf (Rep_File,"%d %s",
Report->UsrFigures.NumFileViews, Report->UsrFigures.NumFileViews,
(Report->UsrFigures.NumFileViews == 1) ? Txt_download : (Report->UsrFigures.NumFileViews == 1) ? Txt_download :
Txt_downloads); Txt_downloads);
if (Report->UsrFigures.NumDays > 0) if (Report->UsrFigures.NumDays > 0)
{ {
fprintf (Gbl.F.Rep," ("); fprintf (Rep_File," (");
Rep_WriteDouble ((double) Report->UsrFigures.NumFileViews / Rep_WriteDouble ((double) Report->UsrFigures.NumFileViews /
(double) Report->UsrFigures.NumDays); (double) Report->UsrFigures.NumDays);
fprintf (Gbl.F.Rep," / %s)",Txt_day); fprintf (Rep_File," / %s)",Txt_day);
} }
} }
else // Number of file views is unknown else // Number of file views is unknown
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
/***** Number of posts in forums *****/ /***** Number of posts in forums *****/
fprintf (Gbl.F.Rep,"<li>%s: ",Txt_Forum_posts); fprintf (Rep_File,"<li>%s: ",Txt_Forum_posts);
if (Report->UsrFigures.NumForumPosts >= 0) if (Report->UsrFigures.NumForumPosts >= 0)
{ {
fprintf (Gbl.F.Rep,"%d %s", fprintf (Rep_File,"%d %s",
Report->UsrFigures.NumForumPosts, Report->UsrFigures.NumForumPosts,
(Report->UsrFigures.NumForumPosts == 1) ? Txt_FORUM_post : (Report->UsrFigures.NumForumPosts == 1) ? Txt_FORUM_post :
Txt_FORUM_posts); Txt_FORUM_posts);
if (Report->UsrFigures.NumDays > 0) if (Report->UsrFigures.NumDays > 0)
{ {
fprintf (Gbl.F.Rep," ("); fprintf (Rep_File," (");
Rep_WriteDouble ((double) Report->UsrFigures.NumForumPosts / Rep_WriteDouble ((double) Report->UsrFigures.NumForumPosts /
(double) Report->UsrFigures.NumDays); (double) Report->UsrFigures.NumDays);
fprintf (Gbl.F.Rep," / %s)",Txt_day); fprintf (Rep_File," / %s)",Txt_day);
} }
} }
else // Number of forum posts is unknown else // Number of forum posts is unknown
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
/***** Number of messages sent *****/ /***** Number of messages sent *****/
fprintf (Gbl.F.Rep,"<li>%s: ",Txt_Messages_sent); fprintf (Rep_File,"<li>%s: ",Txt_Messages_sent);
if (Report->UsrFigures.NumMessagesSent >= 0) if (Report->UsrFigures.NumMessagesSent >= 0)
{ {
fprintf (Gbl.F.Rep,"%d %s", fprintf (Rep_File,"%d %s",
Report->UsrFigures.NumMessagesSent, Report->UsrFigures.NumMessagesSent,
(Report->UsrFigures.NumMessagesSent == 1) ? Txt_message : (Report->UsrFigures.NumMessagesSent == 1) ? Txt_message :
Txt_messages); Txt_messages);
if (Report->UsrFigures.NumDays > 0) if (Report->UsrFigures.NumDays > 0)
{ {
fprintf (Gbl.F.Rep," ("); fprintf (Rep_File," (");
Rep_WriteDouble ((double) Report->UsrFigures.NumMessagesSent / Rep_WriteDouble ((double) Report->UsrFigures.NumMessagesSent /
(double) Report->UsrFigures.NumDays); (double) Report->UsrFigures.NumDays);
fprintf (Gbl.F.Rep," / %s)",Txt_day); fprintf (Rep_File," / %s)",Txt_day);
} }
} }
else // Number of messages sent is unknown else // Number of messages sent is unknown
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</section>\n"); "</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -685,8 +691,8 @@ static void Rep_WriteSectionGlobalHits (struct Rep_Report *Report)
extern const char *Txt_Hits_per_year; extern const char *Txt_Hits_per_year;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s</h3>", "<h3>%s</h3>",
Txt_Hits_per_year); Txt_Hits_per_year);
/***** Global (in any course) hits per year *****/ /***** Global (in any course) hits per year *****/
@ -696,7 +702,7 @@ static void Rep_WriteSectionGlobalHits (struct Rep_Report *Report)
Report); Report);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</section>\n"); fprintf (Rep_File,"</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -719,8 +725,8 @@ static void Rep_WriteSectionHitsPerAction (struct Rep_Report *Report)
unsigned long NumClicks; unsigned long NumClicks;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s</h3>", "<h3>%s</h3>",
Txt_Hits_per_action); Txt_Hits_per_action);
/***** Make the query *****/ /***** Make the query *****/
@ -751,37 +757,37 @@ static void Rep_WriteSectionHitsPerAction (struct Rep_Report *Report)
Rep_DrawBarNumHits (Report->Hits.Num,Report->Hits.Max,Rep_MAX_BAR_WIDTH); Rep_DrawBarNumHits (Report->Hits.Num,Report->Hits.Max,Rep_MAX_BAR_WIDTH);
/* Write action text */ /* Write action text */
fprintf (Gbl.F.Rep,"&nbsp;"); fprintf (Rep_File,"&nbsp;");
if (ActCod >= 0) if (ActCod >= 0)
{ {
if ((Action = Act_FromActCodToAction[ActCod]) >= 0) if ((Action = Act_FromActCodToAction[ActCod]) >= 0)
{ {
Tab = Act_GetTab (Act_GetSuperAction (Action)); Tab = Act_GetTab (Act_GetSuperAction (Action));
if (Txt_TABS_TXT[Tab]) if (Txt_TABS_TXT[Tab])
fprintf (Gbl.F.Rep,"%s &gt; ",Txt_TABS_TXT[Tab]); fprintf (Rep_File,"%s &gt; ",Txt_TABS_TXT[Tab]);
} }
fprintf (Gbl.F.Rep,"%s",Act_GetActionText (Action)); fprintf (Rep_File,"%s",Act_GetActionText (Action));
} }
else else
fprintf (Gbl.F.Rep,"?"); fprintf (Rep_File,"?");
fprintf (Gbl.F.Rep,"<br />"); fprintf (Rep_File,"<br />");
} }
/***** Draw bar for the rest of the clicks *****/ /***** Draw bar for the rest of the clicks *****/
if ((unsigned long) Report->UsrFigures.NumClicks > NumClicks) if ((unsigned long) Report->UsrFigures.NumClicks > NumClicks)
{ {
fprintf (Gbl.F.Rep,"%ld&nbsp;%s", fprintf (Rep_File,"%ld&nbsp;%s",
Report->UsrFigures.NumClicks - NumClicks, Report->UsrFigures.NumClicks - NumClicks,
Txt_Other_actions); Txt_Other_actions);
fprintf (Gbl.F.Rep,"<br />"); fprintf (Rep_File,"<br />");
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</section>\n"); fprintf (Rep_File,"</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -794,13 +800,13 @@ static void Rep_WriteSectionCurrentCourses (struct Rep_Report *Report)
Rol_Role_t Role; Rol_Role_t Role;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s", "<h3>%s",
Txt_Courses); Txt_Courses);
if (Report->CurrentTimeUTC.StrDate[0]) if (Report->CurrentTimeUTC.StrDate[0])
fprintf (Gbl.F.Rep," (%s)",Report->CurrentTimeUTC.StrDate); fprintf (Rep_File," (%s)",Report->CurrentTimeUTC.StrDate);
fprintf (Gbl.F.Rep,"</h3>"); fprintf (Rep_File,"</h3>");
fprintf (Gbl.F.Rep,"<ul>"); fprintf (Rep_File,"<ul>");
/***** Number of courses in which the user is student/teacher *****/ /***** Number of courses in which the user is student/teacher *****/
for (Role = Rol_STD; for (Role = Rol_STD;
@ -810,8 +816,8 @@ static void Rep_WriteSectionCurrentCourses (struct Rep_Report *Report)
Rep_GetAndWriteMyCurrentCrss (Role,Report); Rep_GetAndWriteMyCurrentCrss (Role,Report);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</section>\n"); "</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -826,12 +832,12 @@ static void Rep_WriteSectionHistoricCourses (struct Rep_Report *Report)
Rol_Role_t Role; Rol_Role_t Role;
/***** Begin section *****/ /***** Begin section *****/
fprintf (Gbl.F.Rep,"<section>" fprintf (Rep_File,"<section>"
"<h3>%s (%s)</h3>", "<h3>%s (%s)</h3>",
Txt_Courses,Txt_historical_log); Txt_Courses,Txt_historical_log);
fprintf (Gbl.F.Rep,Txt_Only_courses_with_more_than_X_clicks_are_shown, fprintf (Rep_File,Txt_Only_courses_with_more_than_X_clicks_are_shown,
Rep_MIN_CLICKS_CRS); Rep_MIN_CLICKS_CRS);
fprintf (Gbl.F.Rep,"<ul>"); fprintf (Rep_File,"<ul>");
/********* Historic clicks of a user without course selected ***********/ /********* Historic clicks of a user without course selected ***********/
Rep_GetAndWriteMyHistoricClicsWithoutCrs (Report); Rep_GetAndWriteMyHistoricClicsWithoutCrs (Report);
@ -844,8 +850,8 @@ static void Rep_WriteSectionHistoricCourses (struct Rep_Report *Report)
Rep_GetAndWriteMyHistoricCrss (Role,Report); Rep_GetAndWriteMyHistoricCrss (Role,Report);
/***** End section *****/ /***** End section *****/
fprintf (Gbl.F.Rep,"</ul>" fprintf (Rep_File,"</ul>"
"</section>\n"); "</section>\n");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -892,17 +898,17 @@ static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
long CrsCod; long CrsCod;
NumCrss = Enr_DB_GetNumCrssOfUsrWithARole (Gbl.Usrs.Me.UsrDat.UsrCod,Role); NumCrss = Enr_DB_GetNumCrssOfUsrWithARole (Gbl.Usrs.Me.UsrDat.UsrCod,Role);
fprintf (Gbl.F.Rep,"<li>"); fprintf (Rep_File,"<li>");
fprintf (Gbl.F.Rep,Txt_USER_in_COURSE, fprintf (Rep_File,Txt_USER_in_COURSE,
Txt_ROLES_SINGUL_Abc[Role][Gbl.Usrs.Me.UsrDat.Sex]); Txt_ROLES_SINGUL_Abc[Role][Gbl.Usrs.Me.UsrDat.Sex]);
fprintf (Gbl.F.Rep," %u %s", fprintf (Rep_File," %u %s",
NumCrss, NumCrss,
NumCrss == 1 ? Txt_course : NumCrss == 1 ? Txt_course :
Txt_courses); Txt_courses);
if (NumCrss) if (NumCrss)
{ {
fprintf (Gbl.F.Rep," (%u %s / %u %s):", fprintf (Rep_File," (%u %s / %u %s):",
Enr_DB_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role, Enr_DB_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role,
(1 << Rol_NET) | (1 << Rol_NET) |
(1 << Rol_TCH)), (1 << Rol_TCH)),
@ -915,7 +921,7 @@ static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
if ((NumCrss = Log_DB_GetMyCrssAndHitsPerCrs (&mysql_res,Role))) if ((NumCrss = Log_DB_GetMyCrssAndHitsPerCrs (&mysql_res,Role)))
{ {
/* Heading row */ /* Heading row */
fprintf (Gbl.F.Rep,"<ol>"); fprintf (Rep_File,"<ol>");
/* Write courses */ /* Write courses */
for (NumCrs = 1; for (NumCrs = 1;
@ -934,14 +940,14 @@ static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
} }
/* End table */ /* End table */
fprintf (Gbl.F.Rep,"</ol>"); fprintf (Rep_File,"</ol>");
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);
} }
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -953,8 +959,8 @@ static void Rep_GetAndWriteMyHistoricClicsWithoutCrs (struct Rep_Report *Report)
extern const char *Txt_Hits_without_course_selected; extern const char *Txt_Hits_without_course_selected;
/***** Heading row *****/ /***** Heading row *****/
fprintf (Gbl.F.Rep,"<li>%s:" fprintf (Rep_File,"<li>%s:"
"<ol>", "<ol>",
Txt_Hits_without_course_selected); Txt_Hits_without_course_selected);
/***** Historic clicks *****/ /***** Historic clicks *****/
@ -964,8 +970,8 @@ static void Rep_GetAndWriteMyHistoricClicsWithoutCrs (struct Rep_Report *Report)
false); // Do not write number of users in course false); // Do not write number of users in course
/***** End list *****/ /***** End list *****/
fprintf (Gbl.F.Rep,"</ol>" fprintf (Rep_File,"</ol>"
"</li>"); "</li>");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -987,10 +993,10 @@ static void Rep_GetAndWriteMyHistoricCrss (Rol_Role_t Role,
if ((NumCrss = Log_DB_GetMyHistoricCrss (&mysql_res,Role,Rep_MIN_CLICKS_CRS))) if ((NumCrss = Log_DB_GetMyHistoricCrss (&mysql_res,Role,Rep_MIN_CLICKS_CRS)))
{ {
/* Heading row */ /* Heading row */
fprintf (Gbl.F.Rep,"<li>"); fprintf (Rep_File,"<li>");
fprintf (Gbl.F.Rep,Txt_Hits_as_a_USER, fprintf (Rep_File,Txt_Hits_as_a_USER,
Txt_ROLES_SINGUL_abc[Role][Gbl.Usrs.Me.UsrDat.Sex]); Txt_ROLES_SINGUL_abc[Role][Gbl.Usrs.Me.UsrDat.Sex]);
fprintf (Gbl.F.Rep,":<ol>"); fprintf (Rep_File,":<ol>");
/* Write courses */ /* Write courses */
for (NumCrs = 1; for (NumCrs = 1;
@ -1009,8 +1015,8 @@ static void Rep_GetAndWriteMyHistoricCrss (Rol_Role_t Role,
} }
/* End list */ /* End list */
fprintf (Gbl.F.Rep,"</ol>" fprintf (Rep_File,"</ol>"
"</li>"); "</li>");
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -1042,25 +1048,25 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
Deg_GetDataOfDegreeByCod (&Deg); Deg_GetDataOfDegreeByCod (&Deg);
/***** Begin row *****/ /***** Begin row *****/
fprintf (Gbl.F.Rep,"<li>"); fprintf (Rep_File,"<li>");
if (CrsCod > 0) // CrsCod > 0 in log ==> course selected if (CrsCod > 0) // CrsCod > 0 in log ==> course selected
{ {
if (Crs.CrsCod > 0) // Course exists if (Crs.CrsCod > 0) // Course exists
{ {
/***** Write course full name *****/ /***** Write course full name *****/
fprintf (Gbl.F.Rep,"<strong>%s</strong> -",Crs.FullName); fprintf (Rep_File,"<strong>%s</strong> -",Crs.FullName);
/***** Write year *****/ /***** Write year *****/
if (Crs.Year) if (Crs.Year)
fprintf (Gbl.F.Rep," %s",Txt_YEAR_OF_DEGREE[Crs.Year]); fprintf (Rep_File," %s",Txt_YEAR_OF_DEGREE[Crs.Year]);
/***** Write degree full name *****/ /***** Write degree full name *****/
fprintf (Gbl.F.Rep," %s",Deg.FullName); fprintf (Rep_File," %s",Deg.FullName);
/***** Write number of teachers / students in course *****/ /***** Write number of teachers / students in course *****/
if (WriteNumUsrs) if (WriteNumUsrs)
fprintf (Gbl.F.Rep," (%u %s / %u %s)", fprintf (Rep_File," (%u %s / %u %s)",
Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod, Enr_GetCachedNumUsrsInCrss (HieLvl_CRS,Crs.CrsCod,
1 << Rol_NET | 1 << Rol_NET |
1 << Rol_TCH), 1 << Rol_TCH),
@ -1070,16 +1076,16 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
Txt_students_ABBREVIATION); Txt_students_ABBREVIATION);
} }
else else
fprintf (Gbl.F.Rep,"(%s)",Txt_unknown_removed_course); fprintf (Rep_File,"(%s)",Txt_unknown_removed_course);
} }
else // CrsCod <= 0 in log ==> no course selected else // CrsCod <= 0 in log ==> no course selected
fprintf (Gbl.F.Rep,"(%s)",Txt_no_course_selected); fprintf (Rep_File,"(%s)",Txt_no_course_selected);
/***** Write hits per year for this course *****/ /***** Write hits per year for this course *****/
fprintf (Gbl.F.Rep,"<br />"); fprintf (Rep_File,"<br />");
Rep_ShowMyHitsPerYear (false,CrsCod,Role,Report); Rep_ShowMyHitsPerYear (false,CrsCod,Role,Report);
fprintf (Gbl.F.Rep,"</li>"); fprintf (Rep_File,"</li>");
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1139,13 +1145,13 @@ static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
Year--) Year--)
{ {
/* Write the year */ /* Write the year */
fprintf (Gbl.F.Rep,"%04u&nbsp;",Year); fprintf (Rep_File,"%04u&nbsp;",Year);
/* Draw bar proportional to number of hits */ /* Draw bar proportional to number of hits */
Rep_DrawBarNumHits (Year == ReadYear ? Report->Hits.Num : Rep_DrawBarNumHits (Year == ReadYear ? Report->Hits.Num :
0, 0,
Report->Hits.Max,Rep_MAX_BAR_WIDTH); Report->Hits.Max,Rep_MAX_BAR_WIDTH);
fprintf (Gbl.F.Rep,"<br />"); fprintf (Rep_File,"<br />");
} }
LastYear = Year; LastYear = Year;
} }
@ -1159,11 +1165,11 @@ static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
Year--) Year--)
{ {
/* Write the year */ /* Write the year */
fprintf (Gbl.F.Rep,"%04u&nbsp;",Year); fprintf (Rep_File,"%04u&nbsp;",Year);
/* Draw bar proportional to number of hits */ /* Draw bar proportional to number of hits */
Rep_DrawBarNumHits (0,Report->Hits.Max,Rep_MAX_BAR_WIDTH); Rep_DrawBarNumHits (0,Report->Hits.Max,Rep_MAX_BAR_WIDTH);
fprintf (Gbl.F.Rep,"<br />"); fprintf (Rep_File,"<br />");
} }
} }
@ -1213,16 +1219,16 @@ static void Rep_DrawBarNumHits (unsigned long HitsNum,unsigned long HitsMax,
(double) HitsMax) + 0.5); (double) HitsMax) + 0.5);
if (BarWidth) if (BarWidth)
{ {
fprintf (Gbl.F.Rep,"<strong>"); fprintf (Rep_File,"<strong>");
for (i = 0; for (i = 0;
i < BarWidth; i < BarWidth;
i++) i++)
fprintf (Gbl.F.Rep,Rep_BLOCK); fprintf (Rep_File,Rep_BLOCK);
fprintf (Gbl.F.Rep,"</strong>"); fprintf (Rep_File,"</strong>");
} }
/***** Write the number of hits *****/ /***** Write the number of hits *****/
fprintf (Gbl.F.Rep,"&nbsp;"); fprintf (Rep_File,"&nbsp;");
Rep_WriteDouble (HitsNum); Rep_WriteDouble (HitsNum);
} }
} }
@ -1240,7 +1246,7 @@ static void Rep_WriteDouble (double Num)
Str_DoubleNumToStrFewDigits (&Str,Num); Str_DoubleNumToStrFewDigits (&Str,Num);
/***** Write number from string to file *****/ /***** Write number from string to file *****/
fputs (Str,Gbl.F.Rep); fputs (Str,Rep_File);
/***** Free memory allocated for string *****/ /***** Free memory allocated for string *****/
free (Str); free (Str);

View File

@ -150,8 +150,9 @@ void Set_GetSettingsFromIP (void)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
const char *IP = Par_GetIP ();
if (Gbl.IP[0]) if (IP[0])
{ {
/***** Get settings from database *****/ /***** Get settings from database *****/
if (Set_DB_GetSettingsFromIP (&mysql_res)) if (Set_DB_GetSettingsFromIP (&mysql_res))

View File

@ -27,6 +27,7 @@
#include "swad_database.h" #include "swad_database.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/ /*****************************************************************************/
/*************** External global variables from others modules ***************/ /*************** External global variables from others modules ***************/
@ -435,7 +436,7 @@ void Set_DB_UpdateMyIPSettingsForCurrentIP (void)
" VALUES" " VALUES"
" ('%s',%ld,NOW()," " ('%s',%ld,NOW(),"
"%u,%u,'%s','%s',%u,%u,%u)", "%u,%u,'%s','%s',%u,%u,%u)",
Gbl.IP, Par_GetIP (),
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Prefs.FirstDayOfWeek, Gbl.Prefs.FirstDayOfWeek,
(unsigned) Gbl.Prefs.DateFormat, (unsigned) Gbl.Prefs.DateFormat,
@ -492,7 +493,7 @@ unsigned Set_DB_GetSettingsFromIP (MYSQL_RES **mysql_res)
"PhotoShape" // row[6] "PhotoShape" // row[6]
" FROM set_ip_settings" " FROM set_ip_settings"
" WHERE IP='%s'", " WHERE IP='%s'",
Gbl.IP); Par_GetIP ());
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -190,22 +190,6 @@ void Sta_ResetStats (struct Sta_Stats *Stats)
Stats->RowsPerPage = Sta_DEF_ROWS_PER_PAGE; Stats->RowsPerPage = Sta_DEF_ROWS_PER_PAGE;
} }
/*****************************************************************************/
/**************** Read CGI environment variable REMOTE_ADDR ******************/
/*****************************************************************************/
/*
CGI Environment Variables:
REMOTE_ADDR
The IP address of the remote host making the request.
*/
void Sta_GetRemoteAddr (void)
{
if (getenv ("REMOTE_ADDR"))
Str_Copy (Gbl.IP,getenv ("REMOTE_ADDR"),sizeof (Gbl.IP) - 1);
else
Gbl.IP[0] = '\0';
}
/*****************************************************************************/ /*****************************************************************************/
/******************** Show a form to make a query of clicks ******************/ /******************** Show a form to make a query of clicks ******************/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -152,8 +152,6 @@ struct Sta_Stats
void Sta_ResetStats (struct Sta_Stats *Stats); void Sta_ResetStats (struct Sta_Stats *Stats);
void Sta_GetRemoteAddr (void);
void Sta_AskShowCrsHits (void); void Sta_AskShowCrsHits (void);
void Sta_AskShowGblHits (void); void Sta_AskShowGblHits (void);
void Sta_PutLinkToCourseHits (void); void Sta_PutLinkToCourseHits (void);

View File

@ -841,7 +841,7 @@ static void Syl_PutFormItemSyllabus (struct Syl_Syllabus *Syllabus,
Level * Syl_WIDTH_NUM_SYLLABUS); Level * Syl_WIDTH_NUM_SYLLABUS);
if (Level == 1) if (Level == 1)
HTM_NBSP (); HTM_NBSP ();
Syl_WriteNumItem (NULL,Gbl.F.Out,Level,CodItem); Syl_WriteNumItem (NULL,Fil_GetOutputFile (),Level,CodItem);
HTM_NBSP (); HTM_NBSP ();
HTM_TD_End (); HTM_TD_End ();
} }