hpkg format: Add attributes for declaring users and groups

This commit is contained in:
Ingo Weinhold
2013-05-25 01:12:37 +02:00
parent c82776b2fa
commit 0f4e11e75c
18 changed files with 771 additions and 21 deletions
+1
View File
@@ -0,0 +1 @@
#include <../os/package/User.h>
+19
View File
@@ -18,6 +18,7 @@
#include <package/PackageResolvable.h> #include <package/PackageResolvable.h>
#include <package/PackageResolvableExpression.h> #include <package/PackageResolvableExpression.h>
#include <package/PackageVersion.h> #include <package/PackageVersion.h>
#include <package/User.h>
#include <package/UserSettingsFileInfo.h> #include <package/UserSettingsFileInfo.h>
@@ -86,6 +87,9 @@ public:
const BObjectList<BUserSettingsFileInfo>& const BObjectList<BUserSettingsFileInfo>&
UserSettingsFileInfos() const; UserSettingsFileInfos() const;
const BObjectList<BUser>& Users() const;
const BStringList& Groups() const;
const BObjectList<BPackageResolvable>& ProvidesList() const; const BObjectList<BPackageResolvable>& ProvidesList() const;
const BObjectList<BPackageResolvableExpression>& const BObjectList<BPackageResolvableExpression>&
RequiresList() const; RequiresList() const;
@@ -135,6 +139,12 @@ public:
status_t AddUserSettingsFileInfo( status_t AddUserSettingsFileInfo(
const BUserSettingsFileInfo& info); const BUserSettingsFileInfo& info);
void ClearUsers();
status_t AddUser(const BUser& user);
void ClearGroups();
status_t AddGroup(const BString& group);
void ClearProvidesList(); void ClearProvidesList();
status_t AddProvides(const BPackageResolvable& provides); status_t AddProvides(const BPackageResolvable& provides);
@@ -196,6 +206,8 @@ private:
typedef BObjectList<BUserSettingsFileInfo> typedef BObjectList<BUserSettingsFileInfo>
UserSettingsFileInfoList; UserSettingsFileInfoList;
typedef BObjectList<BUser> UserList;
private: private:
status_t _ReadFromPackageFile( status_t _ReadFromPackageFile(
const PackageFileLocation& fileLocation); const PackageFileLocation& fileLocation);
@@ -218,6 +230,8 @@ private:
const char* field, const char* field,
const UserSettingsFileInfoList& const UserSettingsFileInfoList&
infos); infos);
static status_t _AddUsers(BMessage* archive, const char* field,
const UserList& users);
static status_t _ExtractVersion(BMessage* archive, static status_t _ExtractVersion(BMessage* archive,
const char* field, int32 index, const char* field, int32 index,
@@ -236,6 +250,8 @@ private:
static status_t _ExtractUserSettingsFileInfos( static status_t _ExtractUserSettingsFileInfos(
BMessage* archive, const char* field, BMessage* archive, const char* field,
UserSettingsFileInfoList& _infos); UserSettingsFileInfoList& _infos);
static status_t _ExtractUsers(BMessage* archive,
const char* field, UserList& _users);
private: private:
BString fName; BString fName;
@@ -259,6 +275,9 @@ private:
BObjectList<BGlobalSettingsFileInfo> fGlobalSettingsFileInfos; BObjectList<BGlobalSettingsFileInfo> fGlobalSettingsFileInfos;
BObjectList<BUserSettingsFileInfo> fUserSettingsFileInfos; BObjectList<BUserSettingsFileInfo> fUserSettingsFileInfos;
UserList fUsers;
BStringList fGroups;
ResolvableList fProvidesList; ResolvableList fProvidesList;
ResolvableExpressionList fRequiresList; ResolvableExpressionList fRequiresList;
@@ -45,6 +45,10 @@ enum BPackageInfoAttributeID {
// list of global settings file infos // list of global settings file infos
B_PACKAGE_INFO_USER_SETTINGS_FILES, B_PACKAGE_INFO_USER_SETTINGS_FILES,
// list of user settings file infos // list of user settings file infos
B_PACKAGE_INFO_USERS,
// list of (Unix) users defined/needed
B_PACKAGE_INFO_GROUPS,
// list of (Unix) groups defined/needed
// //
B_PACKAGE_INFO_ENUM_COUNT, B_PACKAGE_INFO_ENUM_COUNT,
}; };
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2013, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__USER_H_
#define _PACKAGE__USER_H_
#include <String.h>
#include <StringList.h>
namespace BPackageKit {
class BUser {
public:
BUser();
BUser(const BString& name,
const BString& realName,
const BString& home, const BString& shell,
const BStringList& groups);
~BUser();
status_t InitCheck() const;
const BString& Name() const;
const BString& RealName() const;
const BString& Home() const;
const BString& Shell() const;
const BStringList& Groups() const;
status_t SetTo(const BString& name,
const BString& realName,
const BString& home, const BString& shell,
const BStringList& groups);
static bool IsValidUserName(const char* name);
private:
BString fName;
BString fRealName;
BString fHome;
BString fShell;
BStringList fGroups;
};
} // namespace BPackageKit
#endif // _PACKAGE__USER_H_
@@ -70,3 +70,10 @@ B_DEFINE_HPKG_ATTRIBUTE(44, UINT, "package:settings-file-update-type",
PACKAGE_SETTINGS_FILE_UPDATE_TYPE) PACKAGE_SETTINGS_FILE_UPDATE_TYPE)
B_DEFINE_HPKG_ATTRIBUTE(45, STRING, "package:settings-file-template", B_DEFINE_HPKG_ATTRIBUTE(45, STRING, "package:settings-file-template",
PACKAGE_SETTINGS_FILE_TEMPLATE) PACKAGE_SETTINGS_FILE_TEMPLATE)
B_DEFINE_HPKG_ATTRIBUTE(46, STRING, "package:user", PACKAGE_USER)
B_DEFINE_HPKG_ATTRIBUTE(47, STRING, "package:user.real-name",
PACKAGE_USER_REAL_NAME)
B_DEFINE_HPKG_ATTRIBUTE(48, STRING, "package:user.home", PACKAGE_USER_HOME)
B_DEFINE_HPKG_ATTRIBUTE(49, STRING, "package:user.shell", PACKAGE_USER_SHELL)
B_DEFINE_HPKG_ATTRIBUTE(50, STRING, "package:user.group", PACKAGE_USER_GROUP)
B_DEFINE_HPKG_ATTRIBUTE(51, STRING, "package:group", PACKAGE_GROUP)
@@ -59,6 +59,16 @@ struct BUserSettingsFileInfoData {
}; };
struct BUserData {
const char* name;
const char* realName;
const char* home;
const char* shell;
const char* const* groups;
size_t groupCount;
};
struct BPackageInfoAttributeValue { struct BPackageInfoAttributeValue {
union { union {
uint64 unsignedInt; uint64 unsignedInt;
@@ -68,6 +78,7 @@ struct BPackageInfoAttributeValue {
BPackageResolvableExpressionData resolvableExpression; BPackageResolvableExpressionData resolvableExpression;
BGlobalSettingsFileInfoData globalSettingsFileInfo; BGlobalSettingsFileInfoData globalSettingsFileInfo;
BUserSettingsFileInfoData userSettingsFileInfo; BUserSettingsFileInfoData userSettingsFileInfo;
BUserData user;
}; };
BPackageInfoAttributeID attributeID; BPackageInfoAttributeID attributeID;
@@ -13,6 +13,7 @@
#include <ByteOrder.h> #include <ByteOrder.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include <Array.h>
#include <util/SinglyLinkedList.h> #include <util/SinglyLinkedList.h>
#include <package/hpkg/ErrorOutput.h> #include <package/hpkg/ErrorOutput.h>
@@ -103,6 +104,7 @@ protected:
class PackageResolvableExpressionAttributeHandler; class PackageResolvableExpressionAttributeHandler;
class GlobalSettingsFileInfoAttributeHandler; class GlobalSettingsFileInfoAttributeHandler;
class UserSettingsFileInfoAttributeHandler; class UserSettingsFileInfoAttributeHandler;
class UserAttributeHandler;
class PackageAttributeHandler; class PackageAttributeHandler;
class LowLevelAttributeHandler; class LowLevelAttributeHandler;
@@ -344,6 +346,25 @@ public:
}; };
class ReaderImplBase::UserAttributeHandler
: public PackageInfoAttributeHandlerBase {
public:
UserAttributeHandler(
BPackageInfoAttributeValue&
packageInfoValue);
virtual status_t HandleAttribute(
AttributeHandlerContext* context, uint8 id,
const AttributeValue& value,
AttributeHandler** _handler);
virtual status_t Delete(AttributeHandlerContext* context);
private:
Array<const char*> fGroups;
};
class ReaderImplBase::PackageAttributeHandler : public AttributeHandler { class ReaderImplBase::PackageAttributeHandler : public AttributeHandler {
public: public:
virtual status_t HandleAttribute( virtual status_t HandleAttribute(
@@ -163,6 +163,12 @@ private:
= B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR; = B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR;
private: private:
PackageAttribute* _AddStringAttribute(BHPKGAttributeID id,
const BString& value,
DoublyLinkedList<PackageAttribute>& list);
inline PackageAttribute* _AddStringAttributeIfNotEmpty(
BHPKGAttributeID id, const BString& value,
DoublyLinkedList<PackageAttribute>& list);
void _WritePackageAttributes( void _WritePackageAttributes(
const PackageAttributeList& attributes); const PackageAttributeList& attributes);
@@ -252,6 +258,16 @@ WriterImplBase::SetFinished(bool finished)
} }
inline WriterImplBase::PackageAttribute*
WriterImplBase::_AddStringAttributeIfNotEmpty(BHPKGAttributeID id,
const BString& value, DoublyLinkedList<PackageAttribute>& list)
{
if (value.IsEmpty())
return NULL;
return _AddStringAttribute(id, value, list);
}
} // namespace BPrivate } // namespace BPrivate
} // namespace BHPKG } // namespace BHPKG
+16
View File
@@ -310,6 +310,22 @@ struct PackageContentListHandler : VersionPolicy::PackageContentHandler {
printf("\n"); printf("\n");
break; break;
case B_PACKAGE_INFO_USERS:
printf("\tuser: %s\n", value.user.name);
if (value.user.realName != NULL)
printf("\t\treal name: %s\n", value.user.realName);
if (value.user.home != NULL)
printf("\t\thome: %s\n", value.user.home);
if (value.user.shell != NULL)
printf("\t\tshell: %s\n", value.user.shell);
for (size_t i = 0; i < value.user.groupCount; i++)
printf("\t\tgroup: %s\n", value.user.groups[i]);
break;
case B_PACKAGE_INFO_GROUPS:
printf("\tgroup: %s\n", value.string);
break;
case B_PACKAGE_INFO_INSTALL_PATH: case B_PACKAGE_INFO_INSTALL_PATH:
printf("\tinstall path: %s\n", value.string); printf("\tinstall path: %s\n", value.string);
break; break;
+1
View File
@@ -105,6 +105,7 @@ BuildPlatformSharedLibrary libpackage_build.so
RepositoryInfo.cpp RepositoryInfo.cpp
Request.cpp Request.cpp
TempfileManager.cpp TempfileManager.cpp
User.cpp
ValidateChecksumJob.cpp ValidateChecksumJob.cpp
$(HPKG_SOURCES) $(HPKG_SOURCES)
+1
View File
@@ -97,6 +97,7 @@ SharedLibrary libpackage.so
RepositoryInfo.cpp RepositoryInfo.cpp
Request.cpp Request.cpp
TempfileManager.cpp TempfileManager.cpp
User.cpp
ValidateChecksumJob.cpp ValidateChecksumJob.cpp
$(HPKG_SOURCES) $(HPKG_SOURCES)
+232 -21
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2011, Oliver Tappe <[email protected]> * Copyright 2011, Oliver Tappe <[email protected]>
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -52,6 +53,8 @@ const char* const BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
"base-package", "base-package",
"global-settings-files", "global-settings-files",
"user-settings-files", "user-settings-files",
"users",
"groups"
}; };
@@ -160,18 +163,20 @@ BPackageInfo::BPackageInfo()
BArchivable(), BArchivable(),
fFlags(0), fFlags(0),
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT), fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
fCopyrightList(5), fCopyrightList(4),
fLicenseList(5), fLicenseList(4),
fURLList(5), fURLList(4),
fSourceURLList(5), fSourceURLList(4),
fGlobalSettingsFileInfos(5, true), fGlobalSettingsFileInfos(4, true),
fUserSettingsFileInfos(5, true), fUserSettingsFileInfos(4, true),
fUsers(4, true),
fGroups(4),
fProvidesList(20, true), fProvidesList(20, true),
fRequiresList(20, true), fRequiresList(20, true),
fSupplementsList(20, true), fSupplementsList(20, true),
fConflictsList(5, true), fConflictsList(4, true),
fFreshensList(5, true), fFreshensList(4, true),
fReplacesList(5) fReplacesList(4)
{ {
} }
@@ -181,18 +186,20 @@ BPackageInfo::BPackageInfo(BMessage* archive, status_t* _error)
BArchivable(archive), BArchivable(archive),
fFlags(0), fFlags(0),
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT), fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
fCopyrightList(5), fCopyrightList(4),
fLicenseList(5), fLicenseList(4),
fURLList(5), fURLList(4),
fSourceURLList(5), fSourceURLList(4),
fGlobalSettingsFileInfos(5, true), fGlobalSettingsFileInfos(4, true),
fUserSettingsFileInfos(5, true), fUserSettingsFileInfos(4, true),
fUsers(4, true),
fGroups(4),
fProvidesList(20, true), fProvidesList(20, true),
fRequiresList(20, true), fRequiresList(20, true),
fSupplementsList(20, true), fSupplementsList(20, true),
fConflictsList(5, true), fConflictsList(4, true),
fFreshensList(5, true), fFreshensList(4, true),
fReplacesList(5) fReplacesList(4)
{ {
status_t error; status_t error;
int32 architecture; int32 architecture;
@@ -216,6 +223,8 @@ BPackageInfo::BPackageInfo(BMessage* archive, status_t* _error)
"global-settings-files", fGlobalSettingsFileInfos)) == B_OK "global-settings-files", fGlobalSettingsFileInfos)) == B_OK
&& (error = _ExtractUserSettingsFileInfos(archive, "user-settings-files", && (error = _ExtractUserSettingsFileInfos(archive, "user-settings-files",
fUserSettingsFileInfos)) == B_OK fUserSettingsFileInfos)) == B_OK
&& (error = _ExtractUsers(archive, "users", fUsers)) == B_OK
&& (error = _ExtractStringList(archive, "groups", fGroups)) == B_OK
&& (error = _ExtractResolvables(archive, "provides", fProvidesList)) && (error = _ExtractResolvables(archive, "provides", fProvidesList))
== B_OK == B_OK
&& (error = _ExtractResolvableExpressions(archive, "requires", && (error = _ExtractResolvableExpressions(archive, "requires",
@@ -326,6 +335,50 @@ BPackageInfo::InitCheck() const
|| fProvidesList.IsEmpty()) || fProvidesList.IsEmpty())
return B_NO_INIT; return B_NO_INIT;
// check global settings files
int32 globalSettingsFileCount = fGlobalSettingsFileInfos.CountItems();
for (int32 i = 0; i < globalSettingsFileCount; i++) {
const BGlobalSettingsFileInfo* info
= fGlobalSettingsFileInfos.ItemAt(i);
status_t error = info->InitCheck();
if (error != B_OK)
return error;
}
// check user settings files
int32 userSettingsFileCount = fUserSettingsFileInfos.CountItems();
for (int32 i = 0; i < userSettingsFileCount; i++) {
const BUserSettingsFileInfo* info = fUserSettingsFileInfos.ItemAt(i);
status_t error = info->InitCheck();
if (error != B_OK)
return error;
}
// check users
int32 userCount = fUsers.CountItems();
for (int32 i = 0; i < userCount; i++) {
const BUser* user = fUsers.ItemAt(i);
status_t error = user->InitCheck();
if (error != B_OK)
return B_NO_INIT;
// make sure the user's groups are specified as groups
const BStringList& userGroups = user->Groups();
int32 groupCount = userGroups.CountStrings();
for (int32 k = 0; k < groupCount; k++) {
const BString& group = userGroups.StringAt(k);
if (!fGroups.HasString(group))
return B_BAD_VALUE;
}
}
// check groups
int32 groupCount = fGroups.CountStrings();
for (int32 i = 0; i< groupCount; i++) {
if (!BUser::IsValidUserName(fGroups.StringAt(i)))
return B_BAD_VALUE;
}
return B_OK; return B_OK;
} }
@@ -449,6 +502,20 @@ BPackageInfo::UserSettingsFileInfos() const
} }
const BObjectList<BUser>&
BPackageInfo::Users() const
{
return fUsers;
}
const BStringList&
BPackageInfo::Groups() const
{
return fGroups;
}
const BObjectList<BPackageResolvable>& const BObjectList<BPackageResolvable>&
BPackageInfo::ProvidesList() const BPackageInfo::ProvidesList() const
{ {
@@ -629,6 +696,13 @@ BPackageInfo::ClearSourceURLList()
} }
status_t
BPackageInfo::AddSourceURL(const BString& url)
{
return fSourceURLList.Add(url) ? B_OK : B_NO_MEMORY;
}
void void
BPackageInfo::ClearGlobalSettingsFileInfos() BPackageInfo::ClearGlobalSettingsFileInfos()
{ {
@@ -671,10 +745,37 @@ BPackageInfo::AddUserSettingsFileInfo(const BUserSettingsFileInfo& info)
} }
status_t void
BPackageInfo::AddSourceURL(const BString& url) BPackageInfo::ClearUsers()
{ {
return fSourceURLList.Add(url) ? B_OK : B_NO_MEMORY; fUsers.MakeEmpty();
}
status_t
BPackageInfo::AddUser(const BUser& user)
{
BUser* newUser = new (std::nothrow) BUser(user);
if (newUser == NULL || !fUsers.AddItem(newUser)) {
delete newUser;
return B_NO_MEMORY;
}
return B_OK;
}
void
BPackageInfo::ClearGroups()
{
fGroups.MakeEmpty();
}
status_t
BPackageInfo::AddGroup(const BString& group)
{
return fGroups.Add(group) ? B_OK : B_NO_MEMORY;
} }
@@ -807,6 +908,8 @@ BPackageInfo::Clear()
fSourceURLList.MakeEmpty(); fSourceURLList.MakeEmpty();
fGlobalSettingsFileInfos.MakeEmpty(); fGlobalSettingsFileInfos.MakeEmpty();
fUserSettingsFileInfos.MakeEmpty(); fUserSettingsFileInfos.MakeEmpty();
fUsers.MakeEmpty();
fGroups.MakeEmpty();
fRequiresList.MakeEmpty(); fRequiresList.MakeEmpty();
fProvidesList.MakeEmpty(); fProvidesList.MakeEmpty();
fSupplementsList.MakeEmpty(); fSupplementsList.MakeEmpty();
@@ -842,6 +945,8 @@ BPackageInfo::Archive(BMessage* archive, bool deep) const
"global-settings-files", fGlobalSettingsFileInfos)) != B_OK "global-settings-files", fGlobalSettingsFileInfos)) != B_OK
|| (error = _AddUserSettingsFileInfos(archive, || (error = _AddUserSettingsFileInfos(archive,
"user-settings-files", fUserSettingsFileInfos)) != B_OK "user-settings-files", fUserSettingsFileInfos)) != B_OK
|| (error = _AddUsers(archive, "users", fUsers)) != B_OK
|| (error = archive->AddStrings("groups", fGroups)) != B_OK
|| (error = _AddResolvables(archive, "provides", fProvidesList)) != B_OK || (error = _AddResolvables(archive, "provides", fProvidesList)) != B_OK
|| (error = _AddResolvableExpressions(archive, "requires", || (error = _AddResolvableExpressions(archive, "requires",
fRequiresList)) != B_OK fRequiresList)) != B_OK
@@ -887,6 +992,8 @@ BPackageInfo::GetConfigString(BString& _string) const
.Write("source-urls", fSourceURLList) .Write("source-urls", fSourceURLList)
.Write("global-settings-files", fGlobalSettingsFileInfos) .Write("global-settings-files", fGlobalSettingsFileInfos)
.Write("user-settings-files", fUserSettingsFileInfos) .Write("user-settings-files", fUserSettingsFileInfos)
.Write("users", fUsers)
.Write("groups", fGroups)
.Write("provides", fProvidesList) .Write("provides", fProvidesList)
.BeginRequires(fBasePackage) .BeginRequires(fBasePackage)
.Write("requires", fRequiresList) .Write("requires", fRequiresList)
@@ -1135,6 +1242,44 @@ BPackageInfo::_AddUserSettingsFileInfos(BMessage* archive, const char* field,
} }
/*static*/ status_t
BPackageInfo::_AddUsers(BMessage* archive, const char* field,
const UserList& users)
{
// construct the field names we need
FieldName nameField(field, ":name");
FieldName realNameField(field, ":realName");
FieldName homeField(field, ":home");
FieldName shellField(field, ":shell");
FieldName groupsField(field, ":groups");
if (!nameField.IsValid() || !realNameField.IsValid() || !homeField.IsValid()
|| !shellField.IsValid() || !groupsField.IsValid())
return B_BAD_VALUE;
// add fields
int32 count = users.CountItems();
for (int32 i = 0; i < count; i++) {
const BUser* user = users.ItemAt(i);
BString groups = user->Groups().Join(" ");
if (groups.IsEmpty() && !user->Groups().IsEmpty())
return B_NO_MEMORY;
status_t error;
if ((error = archive->AddString(nameField, user->Name())) != B_OK
|| (error = archive->AddString(realNameField, user->RealName()))
!= B_OK
|| (error = archive->AddString(homeField, user->Home())) != B_OK
|| (error = archive->AddString(shellField, user->Shell())) != B_OK
|| (error = archive->AddString(groupsField, groups)) != B_OK) {
return error;
}
}
return B_OK;
}
/*static*/ status_t /*static*/ status_t
BPackageInfo::_ExtractVersion(BMessage* archive, const char* field, int32 index, BPackageInfo::_ExtractVersion(BMessage* archive, const char* field, int32 index,
BPackageVersion& _version) BPackageVersion& _version)
@@ -1401,4 +1546,70 @@ BPackageInfo::_ExtractUserSettingsFileInfos(BMessage* archive,
} }
/*static*/ status_t
BPackageInfo::_ExtractUsers(BMessage* archive, const char* field,
UserList& _users)
{
// construct the field names we need
FieldName nameField(field, ":name");
FieldName realNameField(field, ":realName");
FieldName homeField(field, ":home");
FieldName shellField(field, ":shell");
FieldName groupsField(field, ":groups");
if (!nameField.IsValid() || !realNameField.IsValid() || !homeField.IsValid()
|| !shellField.IsValid() || !groupsField.IsValid())
return B_BAD_VALUE;
// get the number of items
type_code type;
int32 count;
if (archive->GetInfo(nameField, &type, &count) != B_OK) {
// the field is missing
return B_OK;
}
// extract fields
for (int32 i = 0; i < count; i++) {
BString name;
status_t error = archive->FindString(nameField, i, &name);
if (error != B_OK)
return error;
BString realName;
error = archive->FindString(realNameField, i, &realName);
if (error != B_OK)
return error;
BString home;
error = archive->FindString(homeField, i, &home);
if (error != B_OK)
return error;
BString shell;
error = archive->FindString(shellField, i, &shell);
if (error != B_OK)
return error;
BString groupsString;
error = archive->FindString(groupsField, i, &groupsString);
if (error != B_OK)
return error;
BStringList groups;
if (!groupsString.Split(" ", false, groups))
return B_NO_MEMORY;
BUser* user = new(std::nothrow) BUser(name, realName, home, shell,
groups);
if (user == NULL || !_users.AddItem(user)) {
delete user;
return B_NO_MEMORY;
}
}
return B_OK;
}
} // namespace BPackageKit } // namespace BPackageKit
+120
View File
@@ -703,6 +703,118 @@ BPackageInfo::Parser::_ParseUserSettingsFileInfos(
} }
void
BPackageInfo::Parser::_ParseUsers(UserList* users)
{
struct UserParser : public ListElementParser {
Parser& parser;
UserList* users;
UserParser(Parser& parser, UserList* users)
:
parser(parser),
users(users)
{
}
virtual void operator()(const Token& token)
{
if (token.type != TOKEN_WORD) {
throw ParseError("expected a user name",
token.pos);
}
BString realName;
BString home;
BString shell;
BStringList groups;
for (;;) {
Token nextToken = parser._NextToken();
if (nextToken.type != TOKEN_WORD) {
parser._RewindTo(nextToken);
break;
}
if (nextToken.text == "real-name") {
nextToken = parser._NextToken();
if (nextToken.type != TOKEN_WORD
&& nextToken.type != TOKEN_QUOTED_STRING) {
throw ParseError("expected string (a user real name)",
nextToken.pos);
}
realName = nextToken.text;
} else if (nextToken.text == "home") {
nextToken = parser._NextToken();
if (nextToken.type != TOKEN_WORD
&& nextToken.type != TOKEN_QUOTED_STRING) {
throw ParseError("expected string (a home path)",
nextToken.pos);
}
home = nextToken.text;
} else if (nextToken.text == "shell") {
nextToken = parser._NextToken();
if (nextToken.type != TOKEN_WORD
&& nextToken.type != TOKEN_QUOTED_STRING) {
throw ParseError("expected string (a shell path)",
nextToken.pos);
}
shell = nextToken.text;
} else if (nextToken.text == "groups") {
for (;;) {
nextToken = parser._NextToken();
if (nextToken.type == TOKEN_WORD) {
if (!groups.Add(nextToken.text))
throw std::bad_alloc();
} else if (nextToken.type == TOKEN_ITEM_SEPARATOR
|| nextToken.type == TOKEN_CLOSE_BRACE) {
parser._RewindTo(nextToken);
break;
} else {
throw ParseError("expected a group name",
nextToken.pos);
}
}
break;
} else {
throw ParseError(
"expected 'real-name', 'home', 'shell', or 'groups'",
nextToken.pos);
}
}
BString templatePath;
Token nextToken = parser._NextToken();
if (nextToken.type == TOKEN_WORD && nextToken.text == "template") {
nextToken = parser._NextToken();
if (nextToken.type != TOKEN_WORD
&& nextToken.type != TOKEN_QUOTED_STRING) {
throw ParseError(
"expected string (a settings template file path)",
nextToken.pos);
}
templatePath = nextToken.text;
} else if (nextToken.type == TOKEN_ITEM_SEPARATOR
|| nextToken.type == TOKEN_CLOSE_BRACE) {
parser._RewindTo(nextToken);
} else {
throw ParseError(
"expected 'template', semicolon, new line or '}'",
nextToken.pos);
}
if (!users->AddItem(new BUser(token.text, realName, home, shell,
groups))) {
throw std::bad_alloc();
}
}
} resolvableExpressionParser(*this, users);
_ParseList(resolvableExpressionParser, false);
}
void void
BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
{ {
@@ -814,6 +926,14 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
&packageInfo->fUserSettingsFileInfos); &packageInfo->fUserSettingsFileInfos);
break; break;
case B_PACKAGE_INFO_USERS:
_ParseUsers(&packageInfo->fUsers);
break;
case B_PACKAGE_INFO_GROUPS:
_ParseStringList(&packageInfo->fGroups);
break;
case B_PACKAGE_INFO_PROVIDES: case B_PACKAGE_INFO_PROVIDES:
_ParseResolvableList(&packageInfo->fProvidesList); _ParseResolvableList(&packageInfo->fProvidesList);
break; break;
+1
View File
@@ -79,6 +79,7 @@ private:
GlobalSettingsFileInfoList* infos); GlobalSettingsFileInfoList* infos);
void _ParseUserSettingsFileInfos( void _ParseUserSettingsFileInfos(
UserSettingsFileInfoList* infos); UserSettingsFileInfoList* infos);
void _ParseUsers(UserList* users);
void _Parse(BPackageInfo* packageInfo); void _Parse(BPackageInfo* packageInfo);
@@ -175,6 +175,37 @@ private:
} }
} }
void _WriteListElement(const BUser* value)
{
_WriteMaybeQuoted(value->Name());
if (!value->RealName().IsEmpty()) {
_Write(" real-name ");
_WriteMaybeQuoted(value->RealName());
}
if (!value->Home().IsEmpty()) {
_Write(" home ");
_WriteMaybeQuoted(value->Home());
}
if (!value->Shell().IsEmpty()) {
_Write(" shell ");
_WriteMaybeQuoted(value->Shell());
}
if (!value->Groups().IsEmpty()) {
_Write(" groups ");
BString groups = value->Groups().Join(" ");
if (groups.IsEmpty()) {
if (fError == B_OK)
fError = B_NO_MEMORY;
return;
}
_Write(groups);
}
}
static inline bool _IsValueEmpty(const char* value) static inline bool _IsValueEmpty(const char* value)
{ {
return value[0] == '\0'; return value[0] == '\0';
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <package/User.h>
#include <ctype.h>
namespace BPackageKit {
BUser::BUser()
:
fName(),
fRealName(),
fHome(),
fShell(),
fGroups()
{
}
BUser::BUser(const BString& name, const BString& realName, const BString& home,
const BString& shell, const BStringList& groups)
:
fName(name),
fRealName(realName),
fHome(home),
fShell(shell),
fGroups(groups)
{
}
BUser::~BUser()
{
}
status_t
BUser::InitCheck() const
{
if (fName.IsEmpty())
return B_NO_INIT;
if (!IsValidUserName(fName))
return B_BAD_VALUE;
return B_OK;
}
const BString&
BUser::Name() const
{
return fName;
}
const BString&
BUser::RealName() const
{
return fRealName;
}
const BString&
BUser::Home() const
{
return fHome;
}
const BString&
BUser::Shell() const
{
return fShell;
}
const BStringList&
BUser::Groups() const
{
return fGroups;
}
status_t
BUser::SetTo(const BString& name, const BString& realName, const BString& home,
const BString& shell, const BStringList& groups)
{
fName = name;
fRealName = realName;
fHome = home;
fShell = shell;
fGroups = groups;
return fGroups.CountStrings() == groups.CountStrings() ? B_OK : B_NO_MEMORY;
}
/*static*/ bool
BUser::IsValidUserName(const char* name)
{
if (name[0] == '\0')
return false;
for (; name[0] != '\0'; name++) {
if (!isalnum(name[0]) && name[0] != '_')
return false;
}
return true;
}
} // namespace BPackageKit
+78
View File
@@ -402,6 +402,69 @@ ReaderImplBase::UserSettingsFileInfoAttributeHandler::HandleAttribute(
return B_OK; return B_OK;
} }
// #pragma mark - UserAttributeHandler
ReaderImplBase::UserAttributeHandler::UserAttributeHandler(
BPackageInfoAttributeValue& packageInfoValue)
:
PackageInfoAttributeHandlerBase(packageInfoValue),
fGroups()
{
}
status_t
ReaderImplBase::UserAttributeHandler::HandleAttribute(
AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
AttributeHandler** _handler)
{
switch (id) {
case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_REAL_NAME:
fPackageInfoValue.user.realName = value.string;
break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_HOME:
fPackageInfoValue.user.home = value.string;
break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SHELL:
fPackageInfoValue.user.shell = value.string;
break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP:
if (!fGroups.Add(value.string))
return B_NO_MEMORY;
break;
default:
if (context->ignoreUnknownAttributes)
break;
context->errorOutput->PrintError("Error: Invalid package "
"attribute section: unexpected package attribute id %d "
"encountered when parsing user settings file info\n",
id);
return B_BAD_DATA;
}
return B_OK;
}
status_t
ReaderImplBase::UserAttributeHandler::Delete(AttributeHandlerContext* context)
{
if (!fGroups.IsEmpty()) {
fPackageInfoValue.user.groups = fGroups.Elements();
fPackageInfoValue.user.groupCount = fGroups.Count();
}
return PackageInfoAttributeHandlerBase::Delete(context);
}
// #pragma mark - PackageAttributeHandler // #pragma mark - PackageAttributeHandler
@@ -569,6 +632,21 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute(
} }
break; break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER:
fPackageInfoValue.user.name = value.string;
fPackageInfoValue.attributeID = B_PACKAGE_INFO_USERS;
if (_handler != NULL) {
*_handler = new(std::nothrow) UserAttributeHandler(
fPackageInfoValue);
if (*_handler == NULL)
return B_NO_MEMORY;
}
break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_GROUP:
fPackageInfoValue.SetTo(B_PACKAGE_INFO_GROUPS, value.string);
break;
default: default:
if (context->ignoreUnknownAttributes) if (context->ignoreUnknownAttributes)
break; break;
+42
View File
@@ -480,6 +480,36 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList,
} }
} }
// user list
const BObjectList<BUser>& users = packageInfo.Users();
for (int32 i = 0; i < users.CountItems(); ++i) {
const BUser* user = users.ItemAt(i);
PackageAttribute* attribute = _AddStringAttribute(
B_HPKG_ATTRIBUTE_ID_PACKAGE_USER, user->Name(), attributeList);
_AddStringAttributeIfNotEmpty(
B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_REAL_NAME, user->RealName(),
attribute->children);
_AddStringAttributeIfNotEmpty(
B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_HOME, user->Home(),
attribute->children);
_AddStringAttributeIfNotEmpty(
B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SHELL, user->Shell(),
attribute->children);
for (int32 k = 0; k < user->Groups().CountStrings(); k++) {
_AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP,
user->Groups().StringAt(k), attribute->children);
}
}
// group list
const BStringList& groups = packageInfo.Groups();
for (int32 i = 0; i < groups.CountStrings(); i++) {
_AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_GROUP,
groups.StringAt(i), attributeList);
}
// checksum (optional, only exists in repositories) // checksum (optional, only exists in repositories)
if (packageInfo.Checksum().Length() > 0) { if (packageInfo.Checksum().Length() > 0) {
PackageAttribute* checksum = new PackageAttribute( PackageAttribute* checksum = new PackageAttribute(
@@ -740,6 +770,18 @@ WriterImplBase::RawWriteBuffer(const void* buffer, size_t size, off_t offset)
} }
WriterImplBase::PackageAttribute*
WriterImplBase::_AddStringAttribute(BHPKGAttributeID id, const BString& value,
DoublyLinkedList<PackageAttribute>& list)
{
PackageAttribute* attribute = new PackageAttribute(id,
B_HPKG_ATTRIBUTE_TYPE_STRING, B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
attribute->string = fPackageStringCache.Get(value);
list.Add(attribute);
return attribute;
}
void void
WriterImplBase::_WritePackageAttributes( WriterImplBase::_WritePackageAttributes(
const PackageAttributeList& packageAttributes) const PackageAttributeList& packageAttributes)