From a420243c8aee95e568db2614ded43749495003cc Mon Sep 17 00:00:00 2001 From: "idk%eng.sun.com" Date: Thu, 20 Sep 2001 23:33:23 +0000 Subject: [PATCH] fix for 57337 [libjar does not retrieve link information] r = dveditz@netscape.com sr = brendan@mozilla.org git-svn-id: svn://10.0.0.236/trunk@103378 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/libjar/nsJAR.cpp | 12 +++- mozilla/modules/libjar/nsZipArchive.cpp | 83 +++++++++++++++++++--- mozilla/modules/libjar/nsZipArchive.h | 10 +++ mozilla/xpinstall/packager/unix/makexpi.pl | 2 +- 4 files changed, 95 insertions(+), 12 deletions(-) diff --git a/mozilla/modules/libjar/nsJAR.cpp b/mozilla/modules/libjar/nsJAR.cpp index 44994a2d851..b09c73abacc 100644 --- a/mozilla/modules/libjar/nsJAR.cpp +++ b/mozilla/modules/libjar/nsJAR.cpp @@ -274,11 +274,17 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile) else { #if defined(XP_UNIX) - char *path; + nsXPIDLCString path; - rv = outFile->GetPath(&path); - if (NS_SUCCEEDED(rv)) + rv = outFile->GetPath(getter_Copies(path)); + if (NS_SUCCEEDED(rv)) + { + if (item->isSymlink) + { + err = mZip.ResolveSymlink(path,item); + } chmod(path, item->mode); + } #endif RestoreModTime(item, outFile); // non-fatal if this fails, ignore errors diff --git a/mozilla/modules/libjar/nsZipArchive.cpp b/mozilla/modules/libjar/nsZipArchive.cpp index 31e35834757..9531033fb86 100644 --- a/mozilla/modules/libjar/nsZipArchive.cpp +++ b/mozilla/modules/libjar/nsZipArchive.cpp @@ -76,10 +76,24 @@ char * strdup(const char *src) #ifdef XP_UNIX #include + #include + #include #elif defined(XP_PC) #include #endif +#ifndef XP_UNIX /* we need to have some constant defined in limits.h and unistd.h */ +# ifndef S_IFMT +# define S_IFMT 0170000 +# endif +# ifndef S_IFLNK +# define S_IFLNK 0120000 +# endif +# ifndef PATH_MAX +# define PATH_MAX 1024 +# endif +#endif /* XP_UNIX */ + #include "zipfile.h" #include "zipstruct.h" #include "nsZipArchive.h" @@ -87,6 +101,7 @@ char * strdup(const char *src) static PRUint16 xtoint(unsigned char *ii); static PRUint32 xtolong(unsigned char *ll); static PRUint16 ExtractMode(PRUint32 ext_attr); +static PRBool IsSymlink(PRUint32 ext_attr); static void dosdate(char *aOutDateStr, PRUint16 aDate); static void dostime(char *aOutTimeStr, PRUint16 aTime); @@ -549,13 +564,19 @@ PRInt32 nsZipArchive::ExtractFile(const char* zipEntry, const char* aOutname) PRInt32 status = ExtractFileToFileDesc(zipEntry, fOut, &item); PR_Close(fOut); - if (status != ZIP_OK) { - PR_Delete(aOutname); + if (status != ZIP_OK) + { + PR_Delete(aOutname); } #if defined(XP_UNIX) - else { - //-- set extracted file permissions - chmod(aOutname, item->mode); + else + { + if (item->isSymlink) + { + status = ResolveSymlink(aOutname,item); + } + //-- set extracted file permissions + chmod(aOutname, item->mode); } #endif return status; @@ -703,8 +724,40 @@ PRInt32 nsZipArchive::FindFree( nsZipFind* aFind ) return ZIP_OK; } - - +#ifdef XP_UNIX +//--------------------------------------------- +// nsZipArchive::ResolveSymlink +//--------------------------------------------- +PRInt32 nsZipArchive::ResolveSymlink(const char *path, nsZipItem *item) +{ + PRInt32 status = ZIP_OK; + if (item->isSymlink) + { + char buf[PATH_MAX+1]; + PRFileDesc * fIn = PR_Open(path, PR_RDONLY, 0644); + if (fIn) + { + PRInt32 length = PATH_MAX; + length = PR_Read(fIn,(void*)buf,length); + PR_Close(fIn); + fIn = 0; + if ( length <= 0 + || (buf[length] = 0, PR_Delete(path)) != 0 + || symlink(buf, path) != 0 ) + { + status = ZIP_ERR_DISK; + } + } else { + status = ZIP_ERR_DISK; + } + if (fIn) + { + PR_Close(fIn); + } + } + return status; +} +#endif //*********************************************************** // nsZipArchive -- private implementation @@ -844,7 +897,9 @@ PRInt32 nsZipArchive::BuildFileList() item->size = xtolong( central->size ); item->realsize = xtolong( central->orglen ); item->crc32 = xtolong( central->crc32 ); - item->mode = ExtractMode(xtolong( central->external_attributes )); + PRUint32 external_attributes = xtolong( central->external_attributes ); + item->mode = ExtractMode( external_attributes ); + item->isSymlink = IsSymlink( external_attributes ); item->time = xtoint( central->time ); item->date = xtoint( central->date ); @@ -1594,6 +1649,18 @@ static PRUint16 ExtractMode(PRUint32 ext_attr) return (PRUint16) ext_attr; } + +/* + * + * Return true if the attributes are for a symbolic link + * + */ + +static PRBool IsSymlink(PRUint32 ext_attr) +{ + return (((ext_attr>>16) & S_IFMT) == S_IFLNK) ? PR_TRUE : PR_FALSE; +} + /* * d o s d a t e * diff --git a/mozilla/modules/libjar/nsZipArchive.h b/mozilla/modules/libjar/nsZipArchive.h index f48bf7e3d22..72f0d450e57 100644 --- a/mozilla/modules/libjar/nsZipArchive.h +++ b/mozilla/modules/libjar/nsZipArchive.h @@ -65,6 +65,7 @@ public: PRUint16 mode; PRUint16 time; PRUint16 date; + PRBool isSymlink; nsZipItem* next; @@ -216,6 +217,15 @@ public: PRInt32 FindFree( nsZipFind *aFind ); +#ifdef XP_UNIX + /** + * ResolveSymLinks + * @param path where the file is located + * @param zipItem the zipItem related to "path" + */ + PRInt32 ResolveSymlink(const char *path, nsZipItem *zipItem); +#endif + private: //--- private members --- diff --git a/mozilla/xpinstall/packager/unix/makexpi.pl b/mozilla/xpinstall/packager/unix/makexpi.pl index f2c35444858..63d0a4f9169 100755 --- a/mozilla/xpinstall/packager/unix/makexpi.pl +++ b/mozilla/xpinstall/packager/unix/makexpi.pl @@ -135,7 +135,7 @@ chdir("$inStagePath/$inComponentName"); print "stripping libs in $inStagePath/$inComponentName...\n"; RecursiveStrip(cwd()); -system("zip -r $inDestPath/$inComponentName.xpi *"); +system("zip -r -y $inDestPath/$inComponentName.xpi *"); chdir("$saveCwdir"); system("cp $inComponentName.js install.js");