PackageWriterImpl::_AddEntry(): Fix update logic

* Don't only look up the entry attribute when the entry is implicit.
  Look it up, when it is a directory instead. This aligns it the logic
  with _UpdateCheckEntryCollisions().
* When the entry attribute exits and the entry is not implicit, add file
  attributes, but not stat data. This also aligns the logic with
  _UpdateCheckEntryCollisions(), which removes colliding attributes, but
  keeps stat data.
This commit is contained in:
Ingo Weinhold 2011-07-03 10:33:12 +02:00
parent 3095cb1bc9
commit 718fba99c8

View File

@ -1567,9 +1567,10 @@ PackageWriterImpl::_AddEntry(int dirFD, Entry* entry, const char* fileName,
// In update mode we don't need to add an entry attribute for an implicit // In update mode we don't need to add an entry attribute for an implicit
// directory, if there already is one. // directory, if there already is one.
if (isImplicitEntry && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { Attribute* entryAttribute = NULL;
Attribute* entryAttribute = fTopAttribute->FindEntryChild(fileName); if (S_ISDIR(st.st_mode) && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) {
if (entryAttribute != NULL) { entryAttribute = fTopAttribute->FindEntryChild(fileName);
if (entryAttribute != NULL && isImplicitEntry) {
Stacker<Attribute> entryAttributeStacker(fTopAttribute, Stacker<Attribute> entryAttributeStacker(fTopAttribute,
entryAttribute); entryAttribute);
_AddDirectoryChildren(entry, fd, pathBuffer); _AddDirectoryChildren(entry, fd, pathBuffer);
@ -1596,49 +1597,55 @@ PackageWriterImpl::_AddEntry(int dirFD, Entry* entry, const char* fileName,
throw status_t(B_UNSUPPORTED); throw status_t(B_UNSUPPORTED);
} }
// add attribute entry // add attribute entry, if it doesn't already exist (update mode, directory)
Attribute* entryAttribute = _AddStringAttribute( bool isNewEntry = entryAttribute == NULL;
B_HPKG_ATTRIBUTE_ID_DIRECTORY_ENTRY, fileName); if (entryAttribute == NULL) {
entryAttribute = _AddStringAttribute(
B_HPKG_ATTRIBUTE_ID_DIRECTORY_ENTRY, fileName);
}
Stacker<Attribute> entryAttributeStacker(fTopAttribute, entryAttribute); Stacker<Attribute> entryAttributeStacker(fTopAttribute, entryAttribute);
// add stat data if (isNewEntry) {
if (fileType != B_HPKG_DEFAULT_FILE_TYPE) // add stat data
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_TYPE, fileType); if (fileType != B_HPKG_DEFAULT_FILE_TYPE)
if (defaultPermissions != uint32(st.st_mode & ALLPERMS)) { _AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_TYPE, fileType);
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_PERMISSIONS, if (defaultPermissions != uint32(st.st_mode & ALLPERMS)) {
uint32(st.st_mode & ALLPERMS)); _AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_PERMISSIONS,
} uint32(st.st_mode & ALLPERMS));
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_ATIME, uint32(st.st_atime)); }
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_MTIME, uint32(st.st_mtime)); _AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_ATIME, uint32(st.st_atime));
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_MTIME, uint32(st.st_mtime));
#ifdef __HAIKU__ #ifdef __HAIKU__
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_CRTIME, uint32(st.st_crtime)); _AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_CRTIME, uint32(st.st_crtime));
#else #else
_AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_CRTIME, uint32(st.st_mtime)); _AddAttribute(B_HPKG_ATTRIBUTE_ID_FILE_CRTIME, uint32(st.st_mtime));
#endif #endif
// TODO: File user/group! // TODO: File user/group!
// add file data/symlink path // add file data/symlink path
if (S_ISREG(st.st_mode)) { if (S_ISREG(st.st_mode)) {
// regular file -- add data // regular file -- add data
if (st.st_size > 0) { if (st.st_size > 0) {
BFDDataReader dataReader(fd); BFDDataReader dataReader(fd);
status_t error = _AddData(dataReader, st.st_size); status_t error = _AddData(dataReader, st.st_size);
if (error != B_OK) if (error != B_OK)
throw status_t(error); throw status_t(error);
} }
} else if (S_ISLNK(st.st_mode)) { } else if (S_ISLNK(st.st_mode)) {
// symlink -- add link address // symlink -- add link address
char path[B_PATH_NAME_LENGTH + 1]; char path[B_PATH_NAME_LENGTH + 1];
ssize_t bytesRead = readlinkat(dirFD, fileName, path, ssize_t bytesRead = readlinkat(dirFD, fileName, path,
B_PATH_NAME_LENGTH); B_PATH_NAME_LENGTH);
if (bytesRead < 0) { if (bytesRead < 0) {
fListener->PrintError("Failed to read symlink \"%s\": %s\n", fListener->PrintError("Failed to read symlink \"%s\": %s\n",
pathBuffer, strerror(errno)); pathBuffer, strerror(errno));
throw status_t(errno); throw status_t(errno);
} }
path[bytesRead] = '\0'; path[bytesRead] = '\0';
_AddStringAttribute(B_HPKG_ATTRIBUTE_ID_SYMLINK_PATH, path); _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_SYMLINK_PATH, path);
}
} }
// add attributes // add attributes