From 3287c33afbb565ad554b995863ff56827854e3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Tue, 14 Apr 2015 19:38:00 +0200 Subject: [PATCH] Version 14.113.1 --- swad_ID.h | 2 +- swad_account.c | 6 +++--- swad_assignment.c | 8 +++---- swad_changelog.h | 3 ++- swad_file_browser.c | 25 ++++++++++++++-------- swad_mail.c | 20 ++++++++--------- swad_notification.c | 4 ++-- swad_preference.c | 4 ++-- swad_string.c | 52 +++++++++++++++++++-------------------------- swad_user.c | 8 +++---- swad_user.h | 3 ++- swad_web_service.c | 4 ++-- swad_zip.c | 37 +++++++++++++++++++++++++------- 13 files changed, 99 insertions(+), 77 deletions(-) diff --git a/swad_ID.h b/swad_ID.h index e746e0e3..6d233c72 100644 --- a/swad_ID.h +++ b/swad_ID.h @@ -38,7 +38,7 @@ #define ID_MIN_LENGTH_USR_ID 5 // This number MUST be >= 3 #define ID_MAX_LENGTH_USR_ID 16 -#define ID_MAX_BYTES_LIST_USRS_IDS (ID_MAX_LENGTH_USR_ID*Cfg_MAX_USRS_IN_LIST*10) +#define ID_MAX_BYTES_LIST_USRS_IDS (ID_MAX_LENGTH_USR_ID*Cfg_MAX_USRS_IN_LIST*10) struct ListIDs { diff --git a/swad_account.c b/swad_account.c index d273db0f..c872ada2 100644 --- a/swad_account.c +++ b/swad_account.c @@ -160,7 +160,7 @@ static void Acc_ShowFormRequestNewAccountWithParams (const char *NewNicknameWith "", The_ClassFormul[Gbl.Prefs.Theme], Txt_Email, - Cns_MAX_BYTES_STRING, + Usr_MAX_BYTES_USR_EMAIL, Txt_HELP_email, NewEmail); @@ -272,7 +272,7 @@ static void Acc_PrintAccountSeparator (void) bool Acc_CreateNewAccountAndLogIn (void) { char NewNicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_WITH_ARROBA+1]; - char NewEmail[Cns_MAX_BYTES_STRING+1]; + char NewEmail[Usr_MAX_BYTES_USR_EMAIL+1]; char NewEncryptedPassword[Cry_LENGTH_ENCRYPTED_STR_SHA512_BASE64+1]; if (Acc_GetParamsNewAccount (NewNicknameWithoutArroba,NewEmail,NewEncryptedPassword)) @@ -361,7 +361,7 @@ static bool Acc_GetParamsNewAccount (char *NewNicknameWithoutArroba, } /***** Step 2/3: Get new e-mail from form *****/ - Par_GetParToText ("NewEmail",NewEmail,Cns_MAX_BYTES_STRING); + Par_GetParToText ("NewEmail",NewEmail,Usr_MAX_BYTES_USR_EMAIL); if (Mai_CheckIfEmailIsValid (NewEmail)) // New e-mail is valid { diff --git a/swad_assignment.c b/swad_assignment.c index 64d0228c..293202ba 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -274,7 +274,7 @@ static void Asg_ShowOneAssignment (long AsgCod) /* Assignment title */ fprintf (Gbl.F.Out,"" - "

%s

", + "
%s
", Gbl.ColorRows[Gbl.RowEvenOdd], Asg.Hidden ? "ASG_TITLE_LIGHT" : "ASG_TITLE", @@ -340,7 +340,7 @@ static void Asg_ShowOneAssignment (long AsgCod) Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (&Asg); fprintf (Gbl.F.Out,"

" - "%s
 

" + "%s

" "" "", Asg.Hidden ? "DAT_LIGHT" : @@ -1649,7 +1649,7 @@ static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Assignment *Asg) NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get groups of an assignment"); /***** Write heading *****/ - fprintf (Gbl.F.Out,"

%s: ", + fprintf (Gbl.F.Out,"

%s: ", Asg->Hidden ? "ASG_GRP_LIGHT" : "ASG_GRP", (NumRows == 1) ? Txt_Group : @@ -1683,7 +1683,7 @@ static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Assignment *Asg) fprintf (Gbl.F.Out,"%s %s", Txt_The_whole_course,Gbl.CurrentCrs.Crs.ShortName); - fprintf (Gbl.F.Out,"

"); + fprintf (Gbl.F.Out,"
"); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); diff --git a/swad_changelog.h b/swad_changelog.h index 6d6001aa..72805154 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -103,11 +103,12 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 14.113 (2015/04/12)" +#define Log_PLATFORM_VERSION "SWAD 14.113.1 (2015/04/14)" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1 /* + Version 14.113.1: Apr 14, 2015 Fixed bug when compressing users' works, reported by José Martínez Aroza. (184484 lines) Version 14.113: Apr 12, 2015 Refactoring code related to frames. (184462 lines) Version 14.112.1: Apr 12, 2015 Refactoring code related to frames with ending buttons. (184583 lines) Version 14.112: Apr 12, 2015 Optimization in frames with ending buttons. diff --git a/swad_file_browser.c b/swad_file_browser.c index b3924465..9944cc66 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -2914,24 +2914,29 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void) struct UsrData UsrDat; /***** Check the number of users whose works will be shown *****/ - if (Usr_CountNumUsrsInEncryptedList ()) // If some users are selected... + if (Usr_CountNumUsrsInEncryptedList ()) // If some users are selected... { if (Gbl.FileBrowser.ZIP.CreateZIP) { - /***** Create zip file with the assignments and works of the selected users *****/ - /* Create temporary directory for the compression of assignments and works */ + /***** Create zip file + with the assignments and works + of the selected users *****/ + /* Create temporary directory + for the compression of assignments and works */ ZIP_CreateTmpDirForCompression (); /* Initialize structure with user's data */ Usr_UsrDataConstructor (&UsrDat); - /* Create temporary directory for each selected user inside the directory used for compression */ + /* Create temporary directory for each selected user + inside the directory used for compression */ Ptr = Gbl.Usrs.Select.All; while (*Ptr) { - Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); + Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod, + Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat); - if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Get user's data from database + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Get user's data from database if (Usr_CheckIfUsrBelongsToCrs (UsrDat.UsrCod,Gbl.CurrentCrs.Crs.CrsCod)) ZIP_CreateDirCompressionUsr (&UsrDat); } @@ -2943,7 +2948,8 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void) ZIP_CreateZIPAsgWrk (); } else - /***** Button to create a zip file with all the works of the selected users *****/ + /***** Button to create a zip file + with all the works of the selected users *****/ ZIP_PutButtonToCreateZIPAsgWrk (); /***** Write top before showing file browser *****/ @@ -2956,9 +2962,10 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void) Ptr = Gbl.Usrs.Select.All; while (*Ptr) { - Par_GetNextStrUntilSeparParamMult (&Ptr,Gbl.Usrs.Other.UsrDat.EncryptedUsrCod,Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); + Par_GetNextStrUntilSeparParamMult (&Ptr,Gbl.Usrs.Other.UsrDat.EncryptedUsrCod, + Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); Usr_GetUsrCodFromEncryptedUsrCod (&Gbl.Usrs.Other.UsrDat); - if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat)) // Get of the database the data of the user + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat)) // Get of the database the data of the user if (Usr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Other.UsrDat.UsrCod,Gbl.CurrentCrs.Crs.CrsCod)) { /***** Show a row with the data of the owner of the works *****/ diff --git a/swad_mail.c b/swad_mail.c index fc5e1a64..7c98d26f 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -878,9 +878,9 @@ bool Mai_CheckIfEmailIsValid (const char *Email) bool ArrobaFound = false; /***** An e-mail address must have a number of characters - 5 <= Length <= Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA *****/ + 5 <= Length <= Mai_MAX_BYTES_USR_EMAIL *****/ if (Length < 5 || - Length > Cns_MAX_BYTES_STRING) + Length > Usr_MAX_BYTES_USR_EMAIL) return false; /***** An e-mail address can have digits, letters, '.', '-' and '_'; @@ -1131,8 +1131,9 @@ void Mai_ShowFormChangeUsrEmail (void) NumEmails ? Txt_New_email : // A new e-mail Txt_Email); // The first e-mail Act_FormStart (ActChgMai); - fprintf (Gbl.F.Out,"", - Cns_MAX_BYTES_STRING, + fprintf (Gbl.F.Out,"", + Usr_MAX_BYTES_USR_EMAIL, Gbl.Usrs.Me.UsrDat.Email); fprintf (Gbl.F.Out,"" ""); @@ -1151,10 +1152,10 @@ void Mai_RemoveEmail (void) { extern const char *Txt_Email_X_removed; extern const char *Txt_You_can_not_delete_your_current_email; - char Email[Cns_MAX_BYTES_STRING+1]; + char Email[Usr_MAX_BYTES_USR_EMAIL+1]; /***** Get new e-mail from form *****/ - Par_GetParToText ("Email",Email,Cns_MAX_BYTES_STRING); + Par_GetParToText ("Email",Email,Usr_MAX_BYTES_USR_EMAIL); if (strcasecmp (Email,Gbl.Usrs.Me.UsrDat.Email)) // Only if not my current e-mail { @@ -1198,10 +1199,10 @@ void Mai_UpdateEmail (void) extern const char *Txt_A_message_has_been_sent_to_email_address_X_to_confirm_that_address; extern const char *Txt_The_email_address_X_had_been_registered_by_another_user; extern const char *Txt_The_email_address_entered_X_is_not_valid; - char NewEmail[Cns_MAX_BYTES_STRING+1]; + char NewEmail[Usr_MAX_BYTES_USR_EMAIL+1]; /***** Get new e-mail from form *****/ - Par_GetParToText ("NewEmail",NewEmail,Cns_MAX_BYTES_STRING); + Par_GetParToText ("NewEmail",NewEmail,Usr_MAX_BYTES_USR_EMAIL); if (Mai_CheckIfEmailIsValid (NewEmail)) // New e-mail is valid { @@ -1402,7 +1403,7 @@ void Mai_ConfirmEmail (void) MYSQL_ROW row; char MailKey[Mai_LENGTH_EMAIL_CONFIRM_KEY+1]; long UsrCod; - char Email[Cns_MAX_BYTES_STRING+1]; + char Email[Usr_MAX_BYTES_USR_EMAIL+1]; bool KeyIsCorrect = false; bool Confirmed; @@ -1473,7 +1474,6 @@ void Mai_ConfirmEmail (void) Usr_WriteFormLogin (); } - /*****************************************************************************/ /****************** Create temporary file for mail content *******************/ /*****************************************************************************/ diff --git a/swad_notification.c b/swad_notification.c index 3e55913f..dbbc0c49 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -1340,7 +1340,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct UsrData *ToUsrDat,unsign extern const char *Txt_TAB_Messages_NO_HTML[Txt_NUM_LANGUAGES]; extern const char *Txt_Notifications_NO_HTML[Txt_NUM_LANGUAGES]; extern const char *Txt_If_you_no_longer_wish_to_receive_email_notifications_NO_HTML[Txt_NUM_LANGUAGES]; - char MailDomain[Cns_MAX_BYTES_STRING+1]; + char MailDomain[Usr_MAX_BYTES_USR_EMAIL+1]; char Query[512]; MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1360,7 +1360,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct UsrData *ToUsrDat,unsign /***** Return 0 notifications and 0 mails when error *****/ *NumNotif = *NumMails = 0; - Str_GetMailBox (ToUsrDat->Email,MailDomain,Cns_MAX_BYTES_STRING); + Str_GetMailBox (ToUsrDat->Email,MailDomain,Usr_MAX_BYTES_USR_EMAIL); if (Mai_CheckIfMailDomainIsAllowedForNotifications (MailDomain)) { /***** Get pending notifications of this user from database ******/ diff --git a/swad_preference.c b/swad_preference.c index 3f709fba..f94d6bff 100644 --- a/swad_preference.c +++ b/swad_preference.c @@ -65,7 +65,7 @@ void Pre_EditPrefs (void) { extern const char *Txt_Language; extern const char *Txt_You_can_only_receive_email_notifications_if_; - char MailDomain[Cns_MAX_BYTES_STRING+1]; + char MailDomain[Usr_MAX_BYTES_USR_EMAIL+1]; /***** Language *****/ Lay_StartRoundFrame (NULL,Txt_Language); @@ -101,7 +101,7 @@ void Pre_EditPrefs (void) { Ntf_PutFormChangeNotifSentByEMail (); - Str_GetMailBox (Gbl.Usrs.Me.UsrDat.Email,MailDomain,Cns_MAX_BYTES_STRING); + Str_GetMailBox (Gbl.Usrs.Me.UsrDat.Email,MailDomain,Usr_MAX_BYTES_USR_EMAIL); if (!Mai_CheckIfMailDomainIsAllowedForNotifications (MailDomain)) Lay_ShowAlert (Lay_WARNING,Txt_You_can_only_receive_email_notifications_if_); } diff --git a/swad_string.c b/swad_string.c index 21617b8d..599e34f2 100644 --- a/swad_string.c +++ b/swad_string.c @@ -2468,38 +2468,30 @@ void Str_ConvertToValidFileName (char *Str) *Ptr == '_' || *Ptr == '-') continue; - switch (*Ptr) - { - case ' ': *Ptr = '_'; break; + if (isspace ((int) *Ptr) || + *Ptr == '\xA0') + *Ptr = '_'; + else + switch (*Ptr) + { + case 'á': case 'à': case 'ä': case 'â': *Ptr = 'a'; break; + case 'é': case 'è': case 'ë': case 'ê': *Ptr = 'e'; break; + case 'í': case 'ì': case 'ï': case 'î': *Ptr = 'i'; break; + case 'ó': case 'ò': case 'ö': case 'ô': *Ptr = 'o'; break; + case 'ú': case 'ù': case 'ü': case 'û': *Ptr = 'u'; break; + case 'ñ': *Ptr = 'n'; break; + case 'ç': *Ptr = 'c'; break; - case 'á': *Ptr = 'a'; break; - case 'é': *Ptr = 'e'; break; - case 'í': *Ptr = 'i'; break; - case 'ó': *Ptr = 'o'; break; - case 'ú': *Ptr = 'u'; break; - case 'ñ': *Ptr = 'n'; break; - case 'ä': *Ptr = 'a'; break; - case 'ë': *Ptr = 'e'; break; - case 'ï': *Ptr = 'i'; break; - case 'ö': *Ptr = 'o'; break; - case 'ü': *Ptr = 'u'; break; - case 'ç': *Ptr = 'c'; break; + case 'Á': case 'À': case 'Ä': case 'Â': *Ptr = 'A'; break; + case 'É': case 'È': case 'Ë': case 'Ê': *Ptr = 'E'; break; + case 'Í': case 'Ì': case 'Ï': case 'Î': *Ptr = 'I'; break; + case 'Ó': case 'Ò': case 'Ö': case 'Ô': *Ptr = 'O'; break; + case 'Ú': case 'Ù': case 'Ü': case 'Û': *Ptr = 'U'; break; + case 'Ñ': *Ptr = 'N'; break; + case 'Ç': *Ptr = 'C'; break; - case 'Á': *Ptr = 'A'; break; - case 'É': *Ptr = 'E'; break; - case 'Í': *Ptr = 'I'; break; - case 'Ó': *Ptr = 'O'; break; - case 'Ú': *Ptr = 'U'; break; - case 'Ñ': *Ptr = 'N'; break; - case 'Ä': *Ptr = 'A'; break; - case 'Ë': *Ptr = 'E'; break; - case 'Ï': *Ptr = 'I'; break; - case 'Ö': *Ptr = 'O'; break; - case 'Ü': *Ptr = 'U'; break; - case 'Ç': *Ptr = 'C'; break; - - default: *Ptr = '-'; break; - } + default: *Ptr = '-'; break; + } } } diff --git a/swad_user.c b/swad_user.c index 6930c01a..e4b5c235 100644 --- a/swad_user.c +++ b/swad_user.c @@ -2588,7 +2588,7 @@ static void Usr_WriteRowGstMainData (unsigned NumUsr,struct UsrData *UsrDat) const char *BgColor; char PhotoURL[PATH_MAX+1]; bool ShowPhoto; - char MailLink[7+Cns_MAX_BYTES_STRING+1]; // mailto:mail_address + char MailLink[7+Usr_MAX_BYTES_USR_EMAIL+1]; // mailto:mail_address struct Institution Ins; /***** Start row *****/ @@ -2670,7 +2670,7 @@ void Usr_WriteRowStdMainData (unsigned NumUsr,struct UsrData *UsrDat,bool PutChe char PhotoURL[PATH_MAX+1]; bool ShowPhoto; bool UsrIsTheMsgSender = false; - char MailLink[7+Cns_MAX_BYTES_STRING+1]; // mailto:mail_address + char MailLink[7+Usr_MAX_BYTES_USR_EMAIL+1]; // mailto:mail_address struct Institution Ins; bool ShowEmail = (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER && UsrDat->Accepted) || Gbl.Usrs.Me.LoggedRole == Rol_DEG_ADM || @@ -2991,7 +2991,7 @@ static void Usr_WriteRowTchMainData (unsigned NumUsr,struct UsrData *UsrDat,bool char PhotoURL[PATH_MAX+1]; bool ShowPhoto; bool UsrIsTheMsgSender = false; - char MailLink[7+Cns_MAX_BYTES_STRING+1]; // mailto:mail_address + char MailLink[7+Usr_MAX_BYTES_USR_EMAIL+1]; // mailto:mail_address struct Institution Ins; bool ShowEmail = UsrDat->Accepted || Gbl.Usrs.Me.LoggedRole == Rol_DEG_ADM || @@ -3164,7 +3164,7 @@ void Usr_WriteRowAdmData (unsigned NumUsr,struct UsrData *UsrDat) const char *BgColor; char PhotoURL[PATH_MAX+1]; bool ShowPhoto; - char MailLink[7+Cns_MAX_BYTES_STRING+1]; // mailto:mail_address + char MailLink[7+Usr_MAX_BYTES_USR_EMAIL+1]; // mailto:mail_address struct Institution Ins; /***** Start row *****/ diff --git a/swad_user.h b/swad_user.h index 7bec5d6d..ed594352 100644 --- a/swad_user.h +++ b/swad_user.h @@ -53,6 +53,7 @@ #define Usr_DEF_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS 12 #define Usr_MAX_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS 60 +#define Usr_MAX_BYTES_USR_EMAIL 127 #define Usr_MAX_LENGTH_USR_LOGIN 127 // @nick, e-mail or ID #define Usr_MAX_BYTES_USR_LOGIN 127 @@ -124,7 +125,7 @@ struct UsrData char FirstName [Usr_MAX_BYTES_NAME+1]; char FullName [(Usr_MAX_BYTES_NAME+1)*3]; Usr_Sex_t Sex; - char Email [Cns_MAX_BYTES_STRING +1]; + char Email [Usr_MAX_BYTES_USR_EMAIL+1]; bool EmailConfirmed; char Photo [Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+1]; // Name of public link to photo Pri_Visibility_t PhotoVisibility; // Who can see user's photo diff --git a/swad_web_service.c b/swad_web_service.c index deaa1cbf..fd425c45 100644 --- a/swad_web_service.c +++ b/swad_web_service.c @@ -625,8 +625,8 @@ int swad__createAccount (struct soap *soap, strncpy (Gbl.Usrs.Me.UsrDat.Nickname,userNickname,Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA); Gbl.Usrs.Me.UsrDat.Nickname[Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA] = '\0'; - strncpy (Gbl.Usrs.Me.UsrDat.Email,userEmail,Cns_MAX_BYTES_STRING); - Gbl.Usrs.Me.UsrDat.Email[Cns_MAX_BYTES_STRING] = '\0'; + strncpy (Gbl.Usrs.Me.UsrDat.Email,userEmail,Usr_MAX_BYTES_USR_EMAIL); + Gbl.Usrs.Me.UsrDat.Email[Usr_MAX_BYTES_USR_EMAIL] = '\0'; ID_ReallocateListIDs (&Gbl.Usrs.Me.UsrDat,1); Gbl.Usrs.Me.UsrDat.IDs.List[0].Confirmed = false; diff --git a/swad_zip.c b/swad_zip.c index 3fb2db46..8873042b 100644 --- a/swad_zip.c +++ b/swad_zip.c @@ -26,6 +26,7 @@ /*****************************************************************************/ #include // For scandir, etc. +#include // For errno #include // For PATH_MAX #include // For system... #include // For strcpy... @@ -245,9 +246,14 @@ void ZIP_CreateTmpDirForCompression (void) void ZIP_CreateDirCompressionUsr (struct UsrData *UsrDat) { - char FullNameAndUsrID[(Usr_MAX_BYTES_NAME+1)*3+ID_MAX_LENGTH_USR_ID+1]; + char FullNameAndUsrID[(Usr_MAX_BYTES_NAME+1)*3+ + ID_MAX_LENGTH_USR_ID+1+ + 10+1]; char PathFolderUsrInsideCrs[PATH_MAX+1]; - char LinkRelTmpUsr[PATH_MAX+1]; + char LinkTmpUsr[PATH_MAX+1]; + char Link[PATH_MAX+1]; + unsigned NumTry; + bool Success; /***** Create a link in the tree of compression with a name that identifies the owner @@ -263,20 +269,35 @@ void ZIP_CreateDirCompressionUsr (struct UsrData *UsrDat) UsrDat->FirstName[0] ? "-" : ""); Str_LimitLengthHTMLStr (FullNameAndUsrID,50); - strcat (FullNameAndUsrID,UsrDat->IDs.List[0].ID); // TODO: What user's ID from the list? - Str_ConvertToValidFileName (FullNameAndUsrID); + strcat (FullNameAndUsrID,UsrDat->IDs.List[0].ID); // First user's ID sprintf (PathFolderUsrInsideCrs,"%s/usr/%02u/%ld", Gbl.CurrentCrs.PathPriv, (unsigned) (UsrDat->UsrCod % 100), UsrDat->UsrCod); - sprintf (LinkRelTmpUsr,"%s/%s/%s/%s", + sprintf (LinkTmpUsr,"%s/%s/%s/%s", Cfg_PATH_SWAD_PRIVATE, Cfg_FOLDER_ZIP, Gbl.FileBrowser.ZIP.TmpDir, FullNameAndUsrID); - if (symlink (PathFolderUsrInsideCrs,LinkRelTmpUsr) != 0) - Lay_ShowErrorAndExit ("Can not create temporary folder for compression."); + + /* Try to create a link named LinkTmpUsr to PathFolderUsrInsideCrs */ + if (symlink (PathFolderUsrInsideCrs,LinkTmpUsr) != 0) + { + for (Success = false, NumTry = 2; + !Success && errno == EEXIST && NumTry<=1000; + NumTry++) + { + // Link exists ==> a former user share the same name and ID + // (probably a unique user has created two or more accounts) + sprintf (Link,"%s-%u",LinkTmpUsr,NumTry); + if (symlink (PathFolderUsrInsideCrs,Link) == 0) + Success = true; + } + + if (!Success) + Lay_ShowErrorAndExit ("Can not create temporary link for compression."); + } } /*****************************************************************************/ @@ -499,7 +520,7 @@ static unsigned long long ZIP_CloneDir (const char *Path,const char *PathClone,c /***** Create clone of subdirectory *****/ if (mkdir (PathFileClone,(mode_t) 0xFFF)) - Lay_ShowErrorAndExit ("Can not create temporary folder for compression."); + Lay_ShowErrorAndExit ("Can not create temporary subfolder for compression."); /***** Clone subtree starting at this this directory *****/ FullSize += ZIP_CloneDir (PathFile,PathFileClone,PathFileInTree);