diff --git a/swad_changelog.h b/swad_changelog.h index 5f483fce..33bcbc44 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -459,12 +459,11 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.83.1 (2019-03-20)" +#define Log_PLATFORM_VERSION "SWAD 18.84 (2019-03-20)" #define CSS_FILE "swad18.83.css" #define JS_FILE "swad18.80.js" /* -Cfg_PATH_FILE_BROWSER_TMP_PUBLIC crece muy rápido. Tal vez debería organizarse en una jerarquía usando las dos primeras letras - + Version 18.84: Mar 20, 2019 Temporary directories for download are created in a two level system to avoid overflow number of directories. (240582 lines) Version 18.83.1: Mar 20, 2019 Fixed bug in removal of old files in a directory. (240561 lines) Version 18.83: Mar 20, 2019 Important optimization on removing of temporary files to increase speed. Code refactoring related to paths and URL. diff --git a/swad_config.h b/swad_config.h index 5c9116ca..02d698f4 100644 --- a/swad_config.h +++ b/swad_config.h @@ -28,9 +28,9 @@ /** Uncomment one of the following installations of SWAD or create your own **/ /*****************************************************************************/ -//#define LOCALHOST_UBUNTU // Comment this line if not applicable +#define LOCALHOST_UBUNTU // Comment this line if not applicable //#define OPENSWAD_ORG // Comment this line if not applicable -#define SWAD_UGR_ES // Comment this line if not applicable +//#define SWAD_UGR_ES // Comment this line if not applicable //#define SWADBERRY_UGR_ES // Comment this line if not applicable /*****************************************************************************/ diff --git a/swad_file_browser.c b/swad_file_browser.c index dee822c2..e809bbac 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -5121,28 +5121,45 @@ void Brw_CreateDirDownloadTmp (void) { static unsigned NumDir = 0; // When this function is called several times in the same execution of the program, each time a new directory is created // This happens when the trees of assignments and works of several users are being listed - // char PathFileBrowserTmpPubl[PATH_MAX + 1]; - char PathPubDirTmp[PATH_MAX + 1]; + char PathUniqueDirL[PATH_MAX + 1]; + char PathUniqueDirR[PATH_MAX + 1]; - /* Example: /var/www/html/swad/tmp/SSujCNWsy4ZOdmgMKYBe0sKPAJu6szaZOQlIlJs_QIY */ + /* Example: /var/www/html/swad/tmp/SS/ujCNWsy4ZOdmgMKYBe0sKPAJu6szaZOQlIlJs_QIY */ /***** If the public directory does not exist, create it *****/ Fil_CreateDirIfNotExists (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC); - /***** Create a new temporary directory. - Important: number of directories inside a directory is limited to 32K in Linux *****/ + /***** Unique temporary directory. + Important: number of directories inside a directory + is limited to 32K in Linux ==> create directories in two levels *****/ + /* 1. Build the name of the directory, splitted in two parts: */ + /* 1a: 2 leftmost chars */ + Gbl.FileBrowser.TmpPubDir.L[0] = Gbl.UniqueNameEncrypted[0]; + Gbl.FileBrowser.TmpPubDir.L[1] = Gbl.UniqueNameEncrypted[1]; + Gbl.FileBrowser.TmpPubDir.L[2] = '\0'; + /* 1b: rest of chars */ if (NumDir) - snprintf (Gbl.FileBrowser.TmpPubDir,sizeof (Gbl.FileBrowser.TmpPubDir), + snprintf (Gbl.FileBrowser.TmpPubDir.R,sizeof (Gbl.FileBrowser.TmpPubDir.R), "%s_%u", - Gbl.UniqueNameEncrypted,NumDir); + &Gbl.UniqueNameEncrypted[2],NumDir); else - Str_Copy (Gbl.FileBrowser.TmpPubDir,Gbl.UniqueNameEncrypted, + Str_Copy (Gbl.FileBrowser.TmpPubDir.R,&Gbl.UniqueNameEncrypted[2], NAME_MAX); - snprintf (PathPubDirTmp,sizeof (PathPubDirTmp), + + /* 2. Create the left directory */ + snprintf (PathUniqueDirL,sizeof (PathUniqueDirL), "%s/%s", - Cfg_PATH_FILE_BROWSER_TMP_PUBLIC,Gbl.FileBrowser.TmpPubDir); - if (mkdir (PathPubDirTmp,(mode_t) 0xFFF)) + Cfg_PATH_FILE_BROWSER_TMP_PUBLIC,Gbl.FileBrowser.TmpPubDir.L); + Fil_CreateDirIfNotExists (PathUniqueDirL); + + /* 3. Create the right directory inside the left one */ + snprintf (PathUniqueDirR,sizeof (PathUniqueDirR), + "%s/%s", + PathUniqueDirL,Gbl.FileBrowser.TmpPubDir.R); + if (mkdir (PathUniqueDirR,(mode_t) 0xFFF)) Lay_ShowErrorAndExit ("Can not create a temporary folder for download."); + + /* 4. Increase number of directory for next call */ NumDir++; } @@ -6543,9 +6560,11 @@ void Brw_CreateTmpPublicLinkToPrivateFile (const char *FullPathIncludingFile, /***** Create, into temporary public directory, a symbolic link to file *****/ snprintf (Link,sizeof (Link), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir,FileName); + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, + FileName); if (symlink (FullPathIncludingFile,Link) != 0) Lay_ShowErrorAndExit ("Can not create temporary link."); } @@ -10365,9 +10384,10 @@ void Brw_GetLinkToDownloadFile (const char *PathInTree,const char *FileName,char /***** Create URL pointing to symbolic link *****/ snprintf (URLWithSpaces,sizeof (URLWithSpaces), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, FileName); } diff --git a/swad_global.h b/swad_global.h index 5ec0f653..44a699cb 100644 --- a/swad_global.h +++ b/swad_global.h @@ -568,7 +568,11 @@ struct Globals bool IsThisTree; // When showing a file browser, is it that corresponding to the clipboard? bool IsThisFile; // When showing a row of a file browser, are we in the path of the clipboard? } Clipboard; - char TmpPubDir[NAME_MAX + 1]; + struct + { + char L[2 + 1]; // Left directory: 2 first chars + char R[NAME_MAX + 1]; // Right directory: rest of chars + } TmpPubDir; bool HiddenLevels[1 + Brw_MAX_DIR_LEVELS]; const char *TxtStyle; const char *InputStyle; diff --git a/swad_media.c b/swad_media.c index 019ad9e4..139bc96b 100644 --- a/swad_media.c +++ b/swad_media.c @@ -1366,36 +1366,32 @@ static void Med_ShowJPG (struct Media *Media, const char *ClassMedia) { extern const char *Txt_File_not_found; - char FileNameMediaPriv[NAME_MAX + 1]; + char FileNameMedia[NAME_MAX + 1]; char FullPathMediaPriv[PATH_MAX + 1]; - char URLTmp[PATH_MAX + 1]; char URL_JPG[PATH_MAX + 1]; /***** Build private path to JPG *****/ - snprintf (FileNameMediaPriv,sizeof (FileNameMediaPriv), + snprintf (FileNameMedia,sizeof (FileNameMedia), "%s.%s", Media->Name,Med_Extensions[Med_JPG]); snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), "%s/%s", - PathMedPriv,FileNameMediaPriv); + PathMedPriv,FileNameMedia); /***** Check if private media file exists *****/ if (Fil_CheckIfPathExists (FullPathMediaPriv)) { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ - Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMediaPriv); + Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMedia); - /***** Build temporary public URL *****/ - snprintf (URLTmp,sizeof (URLTmp), - "%s/%s", - Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir); - - /***** Create URL pointing to symbolic link *****/ + /***** Build URL pointing to symbolic link *****/ snprintf (URL_JPG,sizeof (URL_JPG), - "%s/%s", - URLTmp,FileNameMediaPriv); + "%s/%s/%s/%s", + Cfg_URL_FILE_BROWSER_TMP_PUBLIC, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, + FileNameMedia); /***** Show media *****/ fprintf (Gbl.F.Out,"\"\"",URL_JPG,ClassMedia);Name,Med_Extensions[Med_GIF]); snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), "%s/%s", - PathMedPriv,FileNameMediaPriv); + PathMedPriv,FileNameMedia); /***** Check if private media file exists *****/ - if (Fil_CheckIfPathExists (FullPathMediaPriv)) + if (Fil_CheckIfPathExists (FullPathMediaPriv)) // The animated GIF image { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ - Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMediaPriv); - - /***** Build temporary public URL *****/ - snprintf (URLTmp,sizeof (URLTmp), - "%s/%s", - Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir); + Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMedia); /***** Create URL pointing to symbolic link *****/ snprintf (URL_GIF,sizeof (URL_GIF), - "%s/%s", - URLTmp,FileNameMediaPriv); + "%s/%s/%s/%s", + Cfg_URL_FILE_BROWSER_TMP_PUBLIC, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, + FileNameMedia); /***** Build private path to static PNG image *****/ - snprintf (FileNameMediaPriv,sizeof (FileNameMediaPriv), + snprintf (FileNameMedia,sizeof (FileNameMedia), "%s.png", Media->Name); snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv), "%s/%s", - PathMedPriv,FileNameMediaPriv); + PathMedPriv,FileNameMedia); /***** Check if private media file exists *****/ - if (Fil_CheckIfPathExists (FullPathMediaPriv)) + if (Fil_CheckIfPathExists (FullPathMediaPriv)) // The static PNG image { /***** Create symbolic link from temporary public directory to private file in order to gain access to it for showing/downloading *****/ - Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMediaPriv); + Brw_CreateTmpPublicLinkToPrivateFile (FullPathMediaPriv,FileNameMedia); /***** Create URL pointing to symbolic link *****/ snprintf (URL_PNG,sizeof (URL_PNG), - "%s/%s", - URLTmp,FileNameMediaPriv); + "%s/%s/%s/%s", + Cfg_URL_FILE_BROWSER_TMP_PUBLIC, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, + FileNameMedia); /***** Show static PNG and animated GIF *****/ fprintf (Gbl.F.Out,"
", Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, The_ClassFormOutBoxBold[Gbl.Prefs.Theme]); Ico_PutIconTextLink ("file.svg", Txt_XML_file); diff --git a/swad_zip.c b/swad_zip.c index 9a428375..6f1e0d29 100644 --- a/swad_zip.c +++ b/swad_zip.c @@ -216,9 +216,10 @@ void ZIP_CreateZIPAsgWrk (void) "%s.zip", Txt_works_ZIP_FILE_NAME); snprintf (PathFileZIP,sizeof (PathFileZIP), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, FileNameZIP); snprintf (StrZip,sizeof (StrZip), "nice -n 19 zip -q -r '%s' *", @@ -239,9 +240,10 @@ void ZIP_CreateZIPAsgWrk (void) { /***** Create URL pointing to ZIP file *****/ snprintf (URLWithSpaces,sizeof (URLWithSpaces), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, FileNameZIP); Str_CopyStrChangingSpaces (URLWithSpaces,URL,PATH_MAX); // In HTML, URL must have no spaces @@ -455,9 +457,10 @@ static void ZIP_CompressFolderIntoZIP (void) strcmp (Gbl.FileBrowser.FilFolLnkName,".") ? Gbl.FileBrowser.FilFolLnkName : Txt_ROOT_FOLDER_EXTERNAL_NAMES[Gbl.FileBrowser.Type]); snprintf (PathFileZIP,sizeof (PathFileZIP), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, FileNameZIP); snprintf (StrZip,sizeof (StrZip), "nice -n 19 zip -q -5 -r '%s' *", @@ -478,9 +481,10 @@ static void ZIP_CompressFolderIntoZIP (void) { /***** Create URL pointing to ZIP file *****/ snprintf (URLWithSpaces,sizeof (URLWithSpaces), - "%s/%s/%s", + "%s/%s/%s/%s", Cfg_URL_FILE_BROWSER_TMP_PUBLIC, - Gbl.FileBrowser.TmpPubDir, + Gbl.FileBrowser.TmpPubDir.L, + Gbl.FileBrowser.TmpPubDir.R, FileNameZIP); Str_CopyStrChangingSpaces (URLWithSpaces,URL,PATH_MAX); // In HTML, URL must have no spaces