fix for 57337 [libjar does not retrieve link information]

r  = dveditz@netscape.com
sr = brendan@mozilla.org
This commit is contained in:
idk%eng.sun.com 2001-09-20 23:33:23 +00:00
Родитель 49a563e048
Коммит 254f44efa9
4 изменённых файлов: 95 добавлений и 12 удалений

Просмотреть файл

@ -274,11 +274,17 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
else
{
#if defined(XP_UNIX)
char *path;
nsXPIDLCString path;
rv = outFile->GetPath(&path);
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

Просмотреть файл

@ -76,10 +76,24 @@ char * strdup(const char *src)
#ifdef XP_UNIX
#include <sys/stat.h>
#include <limits.h>
#include <unistd.h>
#elif defined(XP_PC)
#include <io.h>
#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,11 +564,17 @@ PRInt32 nsZipArchive::ExtractFile(const char* zipEntry, const char* aOutname)
PRInt32 status = ExtractFileToFileDesc(zipEntry, fOut, &item);
PR_Close(fOut);
if (status != ZIP_OK) {
if (status != ZIP_OK)
{
PR_Delete(aOutname);
}
#if defined(XP_UNIX)
else {
else
{
if (item->isSymlink)
{
status = ResolveSymlink(aOutname,item);
}
//-- set extracted file permissions
chmod(aOutname, item->mode);
}
@ -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
*

Просмотреть файл

@ -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 ---

Просмотреть файл

@ -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");