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_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_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_program_resource.o swad_project.o swad_project_database.o \
swad_project_resource.o \

View File

@ -114,12 +114,12 @@ static void HTM_SPTxt (const char *Txt);
void HTM_TITLE_Begin (void)
{
fputs ("<title>",Gbl.F.Out);
HTM_Txt ("<title>");
}
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[0])
fputs (Txt,Gbl.F.Out);
fputs (Txt,Fil_GetOutputFile ());
}
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.
*/
#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 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...
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.6: Oct 20, 2022 Code refactoring in syllabus. (333492 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 ListRoomFullNames [Cht_MAX_BYTES_ROOM_FULL_NAMES + 1];
FILE *FileChat;
FILE *FileOut = Fil_GetOutputFile ();
/***** Get the code and the nombre of the room *****/
Par_GetParToText ("RoomCode",RoomCode,Cht_MAX_BYTES_ROOM_CODE);
@ -525,15 +526,15 @@ void Cht_OpenChatWindow (void)
Gbl.Layout.HTMLStartWritten = true;
/***** 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_WriteUntilStrFoundInFileIncludingStr (Gbl.F.Out,FileChat,">",
Str_WriteUntilStrFoundInFileIncludingStr (FileOut,FileChat,">",
Str_NO_SKIP_HTML_COMMENTS);
/***** Write parameters *****/
HTM_PARAM ("nick","N%s",Gbl.Session.Id);
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 ("port","%u",5000);
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);
/***** Copy index.html file until the end *****/
Str_WriteUntilStrFoundInFileIncludingStr (Gbl.F.Out,FileChat,"</html>",
Str_WriteUntilStrFoundInFileIncludingStr (FileOut,FileChat,"</html>",
Str_NO_SKIP_HTML_COMMENTS);
/***** 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_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_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_cryptography.h"
#include "swad_global.h"
#include "swad_parameter.h"
#include "swad_process.h"
/*****************************************************************************/
/**************************** Private constants ******************************/
@ -133,16 +135,16 @@ void Cry_EncryptSHA512Base64 (const char *PlainText,
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
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_UINT + 1];
NumCall++;
snprintf (UniqueNamePlain,sizeof (UniqueNamePlain),"%s-%lx-%lx-%x",
Gbl.IP,
Par_GetIP (),
(long) Dat_GetStartExecutionTimeUTC (),
(long) Gbl.PID,
(long) Prc_GetPID (),
NumCall);
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,"
"CanAnswer ENUM('N','Y') NOT NULL DEFAULT 'N',"
"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(PrnCod,LogCod),"
"INDEX(ClickTime))");
@ -1445,7 +1445,7 @@ mysql> DESCRIBE fir_banned;
3 rows in set (0.00 sec)
*/
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,"
"UnbanTime DATETIME NOT NULL,"
"INDEX(IP,UnbanTime),"
@ -1465,7 +1465,7 @@ mysql> DESCRIBE fir_log;
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS fir_log ("
"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(IP))");
@ -2072,7 +2072,7 @@ mysql> DESCRIBE log_recent;
"ClickTime DATETIME NOT NULL,"
"TimeToGenerate 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),"
"INDEX(ActCod),"
"INDEX(CtyCod),"
@ -2463,7 +2463,7 @@ mysql> DESCRIBE plg_plugins;
"Logo VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_LOGO
"AppKey VARCHAR(31) NOT NULL," // Plg_MAX_BYTES_PLUGIN_APP_KEY
"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))");
/***** Table prg_clipboards *****/
@ -2880,7 +2880,7 @@ mysql> DESCRIBE set_ip_settings;
10 rows in set (0,01 sec)
*/
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,"
"LastChange DATETIME NOT NULL,"
"FirstDayOfWeek TINYINT NOT NULL DEFAULT 0,"

View File

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

View File

@ -36,6 +36,7 @@
#include "swad_exam_print.h"
#include "swad_exam_set.h"
#include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/
/************** 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_GetIfCanAnswer () ? 'Y' :
'N',
// NOW() Redundant, for speed
Gbl.IP); // Redundant, for speed
// NOW() Redundant, for speed
Par_GetIP ()); // Redundant, for speed
}
/*****************************************************************************/

View File

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

View File

@ -56,7 +56,7 @@ extern struct Globals Gbl;
/***************************** Private constants *****************************/
/*****************************************************************************/
#define NUM_BYTES_PER_CHUNK 4096
#define Fil_NUM_BYTES_PER_CHUNK 4096
static struct
{
@ -68,6 +68,7 @@ static struct
/*****************************************************************************/
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 ********************************/
@ -78,6 +79,20 @@ FILE *Fil_GetQueryFile (void)
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 **********/
/*****************************************************************************/
@ -92,9 +107,9 @@ void Fil_CreateFileForHTMLOutput (void)
"%s/%s.html",Cfg_PATH_OUT_PRIVATE,Cry_GetUniqueNameEncrypted ());
/***** 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.");
}
}
@ -105,12 +120,12 @@ void Fil_CreateFileForHTMLOutput (void)
void Fil_CloseAndRemoveFileForHTMLOutput (void)
{
if (Gbl.F.Out)
if (Fil_Out)
{
fclose (Gbl.F.Out);
fclose (Fil_Out);
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)
{
FILE *FileDataTmp;
unsigned char Bytes[NUM_BYTES_PER_CHUNK];
unsigned char Bytes[Fil_NUM_BYTES_PER_CHUNK];
size_t RemainingBytesToCopy;
size_t BytesToCopy;
FILE *QueryFile = Fil_GetQueryFile ();
@ -297,8 +312,8 @@ bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param)
RemainingBytesToCopy != 0;
RemainingBytesToCopy -= BytesToCopy)
{
BytesToCopy = (RemainingBytesToCopy >= NUM_BYTES_PER_CHUNK) ? NUM_BYTES_PER_CHUNK :
RemainingBytesToCopy;
BytesToCopy = (RemainingBytesToCopy >= Fil_NUM_BYTES_PER_CHUNK) ? Fil_NUM_BYTES_PER_CHUNK :
RemainingBytesToCopy;
if (fread (Bytes,1,BytesToCopy,QueryFile) != BytesToCopy)
{
fclose (FileDataTmp);
@ -567,26 +582,14 @@ void Fil_FastCopyOfFiles (const char *PathSrc,const char *PathTgt)
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;
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);
}
/*****************************************************************************/
/***************************** 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 *********/
/*****************************************************************************/

View File

@ -44,13 +44,6 @@
// 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
// 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)
/*****************************************************************************/
@ -58,6 +51,9 @@ struct Fil_Files
/*****************************************************************************/
FILE *Fil_GetQueryFile (void);
void Fil_SetOutputFileToStdout (void);
FILE *Fil_GetOutputFile (void);
void Fil_CreateFileForHTMLOutput (void);
void Fil_CloseAndRemoveFileForHTMLOutput (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_FastCopyOfOpenFiles (FILE *FileSrc,FILE *FileTgt);
void Fil_CloseReportFile (void);
void Fil_WriteFileSizeBrief (double SizeInBytes,
char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]);
void Fil_WriteFileSizeFull (double SizeInBytes,

View File

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

View File

@ -49,6 +49,7 @@
#include "swad_link.h"
#include "swad_parameter.h"
#include "swad_plugin.h"
#include "swad_process.h"
#include "swad_program.h"
#include "swad_project.h"
#include "swad_role.h"
@ -85,8 +86,8 @@ void Gbl_InitializeGlobals (void)
Dat_SetStartExecutionTimeUTC ();
Dat_GetAndConvertCurrentDateTime ();
Gbl.PID = getpid ();
Sta_GetRemoteAddr ();
Prc_SetPID ();
Par_SetIP ();
Cry_CreateUniqueNameEncrypted (Cry_GetUniqueNameEncrypted ());
@ -94,8 +95,7 @@ void Gbl_InitializeGlobals (void)
Gbl.WebService.IsWebService = false;
Gbl.F.Out = stdout;
Gbl.F.Rep = NULL; // Report
Fil_SetOutputFileToStdout ();
Gbl.Prefs.Language = Txt_Current_CGI_SWAD_Language;
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_FreeListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected);
Syl_FreeListItemsSyllabus ();
Fil_CloseReportFile ();
Par_FreeParams ();
Ale_ResetAllAlerts ();
}

View File

@ -50,9 +50,6 @@
struct Globals
{
struct Fil_Files F;
pid_t PID; // PID of current process
char IP[Cns_MAX_BYTES_IP + 1];
struct
{
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.");
/* 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 */
fclose (FileHTML);

View File

@ -63,6 +63,7 @@
#include "swad_notice.h"
#include "swad_notification.h"
#include "swad_parameter.h"
#include "swad_process.h"
#include "swad_setting.h"
#include "swad_setting_database.h"
#include "swad_tab.h"
@ -1363,42 +1364,43 @@ void Lay_RefreshNotifsAndConnected (void)
unsigned NumUsr;
bool ShowConnected = (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) &&
Gbl.Hierarchy.Level == HieLvl_CRS; // Right column visible && There is a course selected
pid_t PID = Prc_GetPID ();
/***** Sometimes, someone must do this work,
so who best than processes that refresh via AJAX? *****/
// 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
else if (!(Gbl.PID % 19))
else if (!(PID % 19))
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,
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)
else if (!(Gbl.PID % 103))
else if (!(PID % 103))
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
else if (!(Gbl.PID % 109))
else if (!(PID % 109))
Fil_RemoveOldTmpFiles (Cfg_PATH_OUT_PRIVATE,
Cfg_TIME_TO_DELETE_HTML_OUTPUT ,false);
else if (!(Gbl.PID % 113))
else if (!(PID % 113))
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PUBLIC,
Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
else if (!(Gbl.PID % 127))
else if (!(PID % 127))
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PRIVATE,
Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
else if (!(Gbl.PID % 131))
else if (!(PID % 131))
Fil_RemoveOldTmpFiles (Cfg_PATH_MEDIA_TMP_PRIVATE,
Cfg_TIME_TO_DELETE_MEDIA_TMP_FILES ,false);
else if (!(Gbl.PID % 137))
else if (!(PID % 137))
Fil_RemoveOldTmpFiles (Cfg_PATH_ZIP_PRIVATE,
Cfg_TIME_TO_DELETE_BROWSER_ZIP_FILES,false);
else if (!(Gbl.PID % 139))
else if (!(PID % 139))
Fil_RemoveOldTmpFiles (Cfg_PATH_MARK_PRIVATE,
Cfg_TIME_TO_DELETE_MARKS_TMP_FILES ,false);
else if (!(Gbl.PID % 149))
else if (!(PID % 149))
Fil_RemoveOldTmpFiles (Cfg_PATH_TEST_PRIVATE,
Cfg_TIME_TO_DELETE_TEST_TMP_FILES ,false);
@ -1455,7 +1457,7 @@ static void Lay_WriteFootFromHTMLFile (void)
HTM_Txt ("<footer id=\"foot_zone\">");
/***** Copy HTML to output file *****/
Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out);
Fil_FastCopyOfOpenFiles (FileHTML,Fil_GetOutputFile ());
fclose (FileHTML);
HTM_Txt ("</footer>");

View File

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

View File

@ -609,7 +609,7 @@ void Mrk_ShowMyMarks (void)
Gbl.Layout.HTMLStartWritten = true;
/* Copy HTML to output file */
Fil_FastCopyOfOpenFiles (FileUsrMarks,Gbl.F.Out);
Fil_FastCopyOfOpenFiles (FileUsrMarks,Fil_GetOutputFile ());
fclose (FileUsrMarks);
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 *****/
if (ChangeBRToRet)
Str_FilePrintStrChangingBRToRetAndNBSPToSpace (Gbl.F.Out,Content);
Str_FilePrintStrChangingBRToRetAndNBSPToSpace (Fil_GetOutputFile (),Content);
else
HTM_Txt (Content);
}

View File

@ -83,6 +83,7 @@ static struct
size_t LengthWithoutCRLF;
size_t LengthWithCRLF;
} Boundary;
char IP[Par_MAX_BYTES_IP + 1];
} Par_Params =
{
.ContentReceivedByCGI = Act_CONT_NORM,
@ -1145,3 +1146,24 @@ void Par_PutHiddenParamString (const char *Id,const char *ParamName,
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_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 *****************************/
/*****************************************************************************/
@ -102,4 +108,8 @@ void Par_PutHiddenParamChar (const char *ParamName,char Value);
void Par_PutHiddenParamString (const char *Id,const char *ParamName,
const char *Value);
//----------------------------- Client IP address -----------------------------
void Par_SetIP (void);
const char *Par_GetIP (void);
#endif

View File

@ -426,7 +426,7 @@ static void Plg_ListPluginsForEdition (void)
HTM_TD_Begin ("class=\"CM\"");
Frm_BeginForm (ActChgPlgIP);
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\"",
The_GetSuffix ());
Frm_EndForm ();
@ -718,7 +718,7 @@ void Plg_ChangePlgURL (void)
void Plg_ChangePlgIP (void)
{
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 *****/
Plg_EditingPluginConstructor ();
@ -729,7 +729,7 @@ void Plg_ChangePlgIP (void)
Err_WrongPluginExit ();
/* 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 *****/
Plg_GetDataOfPluginByCod (Plg_EditingPlg);
@ -851,7 +851,7 @@ static void Plg_PutFormToCreatePlugin (void)
/***** Plugin IP address *****/
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,
"size=\"10\" class=\"INPUT_%s\""
" required=\"required\"",
@ -926,7 +926,7 @@ void Plg_ReceiveFormNewPlg (void)
Par_GetParToText ("URL",Plg_EditingPlg->URL,Cns_MAX_BYTES_WWW);
/* 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
{

View File

@ -23,6 +23,12 @@
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_parameter.h"
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
@ -51,7 +57,7 @@ struct Plg_Plugin
char Logo[Plg_MAX_BYTES_PLUGIN_LOGO + 1];
char AppKey[Plg_MAX_BYTES_PLUGIN_APP_KEY + 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,
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",
"UPDATE plg_plugins"

View File

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

View File

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

View File

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

View File

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

View File

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