144f919daSRyan Leavengood/*
2091440e0SStephan Aßmus * Copyright (c) 2007-2010, Haiku, Inc.
344f919daSRyan Leavengood * Distributed under the terms of the MIT license.
444f919daSRyan Leavengood *
544f919daSRyan Leavengood * Author:
644f919daSRyan Leavengood *		��ukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
744f919daSRyan Leavengood */
844f919daSRyan Leavengood
9f51cdb44SStephan Aßmus
1044f919daSRyan Leavengood#include "PackageInfo.h"
1144f919daSRyan Leavengood
1244f919daSRyan Leavengood#include <Alert.h>
1344f919daSRyan Leavengood#include <ByteOrder.h>
14091440e0SStephan Aßmus#include <Catalog.h>
1544f919daSRyan Leavengood#include <FindDirectory.h>
16091440e0SStephan Aßmus#include <Locale.h>
1744f919daSRyan Leavengood#include <Path.h>
1844f919daSRyan Leavengood#include <kernel/OS.h>
1944f919daSRyan Leavengood
2044f919daSRyan Leavengood
21546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
22546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "PackageInfo"
2344f919daSRyan Leavengood
240064d324SJérôme Duval#define RETURN_AND_SET_STATUS(err) fStatus = err; \
250064d324SJérôme Duval	fprintf(stderr, "err at %s():%d: %x\n", __FUNCTION__, __LINE__, err); \
260064d324SJérôme Duval	return fStatus;
270064d324SJérôme Duval
2844f919daSRyan Leavengoodconst uint32 kSkipOffset = 33;
2944f919daSRyan Leavengood
3044f919daSRyan Leavengood// Section constants
3144f919daSRyan Leavengoodenum {
3244f919daSRyan Leavengood	P_GROUPS_SECTION = 0,
3344f919daSRyan Leavengood	P_PATH_SECTION,
3444f919daSRyan Leavengood	P_USER_PATH_SECTION,
3544f919daSRyan Leavengood	P_LICENSE_SECTION
3644f919daSRyan Leavengood};
3744f919daSRyan Leavengood
3844f919daSRyan Leavengood
3944f919daSRyan Leavengood// Element constants
4044f919daSRyan Leavengoodenum {
4144f919daSRyan Leavengood	P_NONE = 0,
4244f919daSRyan Leavengood	P_FILE,
4344f919daSRyan Leavengood	P_DIRECTORY,
449ff2343bSJérôme Duval	P_LINK,
459ff2343bSJérôme Duval	P_SCRIPT
4644f919daSRyan Leavengood};
4744f919daSRyan Leavengood
481bc7045fSPawel Dziepaktypedef enum {
49aa7f93c5SRob Gill	B_BEBOX_PLATFORM = 0,
50aa7f93c5SRob Gill	B_MAC_PLATFORM,
51aa7f93c5SRob Gill	B_AT_CLONE_PLATFORM,
52aa7f93c5SRob Gill	B_ENIAC_PLATFORM,
53aa7f93c5SRob Gill	B_APPLE_II_PLATFORM,
54aa7f93c5SRob Gill	B_CRAY_PLATFORM,
55aa7f93c5SRob Gill	B_LISA_PLATFORM,
56aa7f93c5SRob Gill	B_TI_994A_PLATFORM,
57aa7f93c5SRob Gill	B_TIMEX_SINCLAIR_PLATFORM,
58aa7f93c5SRob Gill	B_ORAC_1_PLATFORM,
59aa7f93c5SRob Gill	B_HAL_PLATFORM,
601bc7045fSPawel Dziepak	B_INVALID_PLATFORM
611bc7045fSPawel Dziepak} platform_type;
621bc7045fSPawel Dziepak
6344f919daSRyan Leavengood
6444f919daSRyan LeavengoodPackageInfo::PackageInfo()
657974d3dcSStephan Aßmus	:
6644f919daSRyan Leavengood	fStatus(B_NO_INIT),
6744f919daSRyan Leavengood	fPackageFile(0),
68eef95624SMatt Madia	fDescription(B_TRANSLATE("No package available.")),
6944f919daSRyan Leavengood	fProfiles(2),
7044f919daSRyan Leavengood	fHasImage(false)
7144f919daSRyan Leavengood{
7244f919daSRyan Leavengood}
7344f919daSRyan Leavengood
7444f919daSRyan Leavengood
7544f919daSRyan LeavengoodPackageInfo::PackageInfo(const entry_ref *ref)
767974d3dcSStephan Aßmus	:
7744f919daSRyan Leavengood	fStatus(B_NO_INIT),
7844f919daSRyan Leavengood	fPackageFile(new BFile(ref, B_READ_ONLY)),
79eef95624SMatt Madia	fDescription(B_TRANSLATE("No package selected.")),
8044f919daSRyan Leavengood	fProfiles(2),
8144f919daSRyan Leavengood	fHasImage(false)
8244f919daSRyan Leavengood{
8344f919daSRyan Leavengood	fStatus = Parse();
8444f919daSRyan Leavengood}
8544f919daSRyan Leavengood
8644f919daSRyan Leavengood
8744f919daSRyan LeavengoodPackageInfo::~PackageInfo()
8844f919daSRyan Leavengood{
8944f919daSRyan Leavengood	pkg_profile *iter = 0;
9044f919daSRyan Leavengood	while (1) {
91bd380b55SJérôme Duval		iter = static_cast<pkg_profile *>(fProfiles.RemoveItem((int32)0));
9278c00a4aSAxel Dörfler		if (iter == NULL)
9344f919daSRyan Leavengood			break;
9478c00a4aSAxel Dörfler
9578c00a4aSAxel Dörfler		delete iter;
9644f919daSRyan Leavengood	}
9744f919daSRyan Leavengood
9878c00a4aSAxel Dörfler	PackageItem *file = 0;
9978c00a4aSAxel Dörfler	while (true) {
100bd380b55SJérôme Duval		file = static_cast<PackageItem *>(fFiles.RemoveItem((int32)0));
10178c00a4aSAxel Dörfler		if (file == NULL)
10244f919daSRyan Leavengood			break;
10378c00a4aSAxel Dörfler
10478c00a4aSAxel Dörfler		delete file;
10544f919daSRyan Leavengood	}
10644f919daSRyan Leavengood
1079ff2343bSJérôme Duval	while (true) {
108bd380b55SJérôme Duval		file = static_cast<PackageScript *>(fScripts.RemoveItem((int32)0));
1099ff2343bSJérôme Duval		if (file == NULL)
1109ff2343bSJérôme Duval			break;
1119ff2343bSJérôme Duval
1129ff2343bSJérôme Duval		delete file;
1139ff2343bSJérôme Duval	}
1149ff2343bSJérôme Duval
11578c00a4aSAxel Dörfler	delete fPackageFile;
11644f919daSRyan Leavengood}
11744f919daSRyan Leavengood
11844f919daSRyan Leavengood
11944f919daSRyan Leavengoodstatus_t
12044f919daSRyan LeavengoodPackageInfo::Parse()
12144f919daSRyan Leavengood{
12244f919daSRyan Leavengood	// TODO: Clean up
12344f919daSRyan Leavengood	if (!fPackageFile || fPackageFile->InitCheck() != B_OK) {
1240064d324SJérôme Duval		RETURN_AND_SET_STATUS(B_ERROR);
12544f919daSRyan Leavengood	}
1267974d3dcSStephan Aßmus
12744f919daSRyan Leavengood	// Check for the presence of the first AlB tag - as the 'magic number'.
12844f919daSRyan Leavengood	// This also ensures that the file header section is present - which
12944f919daSRyan Leavengood	// is a crucial pkg section
13044f919daSRyan Leavengood	char buffer[16];
13144f919daSRyan Leavengood	fPackageFile->Read(buffer, 8);
1327974d3dcSStephan Aßmus	if (buffer[0] != 'A' || buffer[1] != 'l' || buffer[2] != 'B'
13344f919daSRyan Leavengood		|| buffer[3] != 0x1a) {
1340064d324SJérôme Duval		RETURN_AND_SET_STATUS(B_ERROR);
13544f919daSRyan Leavengood	}
13644f919daSRyan Leavengood
13744f919daSRyan Leavengood	fHasImage = false;
13844f919daSRyan Leavengood
13944f919daSRyan Leavengood	// Parse all known parts of the given .pkg file
1407974d3dcSStephan Aßmus
14144f919daSRyan Leavengood	uint32 i;
14244f919daSRyan Leavengood	int8 bytesRead;
14344f919daSRyan Leavengood	off_t actualSize = 0;
14444f919daSRyan Leavengood	fPackageFile->GetSize(&actualSize);
14544f919daSRyan Leavengood	uint64 fileSize = 0;
14678c00a4aSAxel Dörfler
14744f919daSRyan Leavengood	const char padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
14844f919daSRyan Leavengood
1491bc7045fSPawel Dziepak	platform_type thisPlatform = B_INVALID_PLATFORM;
1501bc7045fSPawel Dziepak	cpu_topology_node_info topologyRoot;
1511bc7045fSPawel Dziepak	uint32 topologyNodeCount = 1;
1521bc7045fSPawel Dziepak	if (get_cpu_topology_info(&topologyRoot, &topologyNodeCount) == B_OK) {
1531bc7045fSPawel Dziepak		switch (topologyRoot.data.root.platform) {
1541bc7045fSPawel Dziepak			case B_CPU_x86:
1551bc7045fSPawel Dziepak				thisPlatform = B_AT_CLONE_PLATFORM;
1561bc7045fSPawel Dziepak				break;
1571bc7045fSPawel Dziepak
1581bc7045fSPawel Dziepak			default:
1591bc7045fSPawel Dziepak				break;
1601bc7045fSPawel Dziepak		}
1611bc7045fSPawel Dziepak	}
1627974d3dcSStephan Aßmus
16344f919daSRyan Leavengood	uint64 infoOffset = 0, groupsOffset = 0;
16444f919daSRyan Leavengood	uint64 length = 0;
16578c00a4aSAxel Dörfler
16644f919daSRyan Leavengood	// Parse the file header
16778c00a4aSAxel Dörfler	while (true) {
16844f919daSRyan Leavengood		bytesRead = fPackageFile->Read(buffer, 7);
16944f919daSRyan Leavengood		if (bytesRead != 7) {
1700064d324SJérôme Duval			RETURN_AND_SET_STATUS(B_ERROR);
17144f919daSRyan Leavengood		}
17244f919daSRyan Leavengood
17344f919daSRyan Leavengood		if (!memcmp(buffer, "PhIn", 5)) {
17478c00a4aSAxel Dörfler		} else if (!memcmp(buffer, "FVer", 5)) {
17544f919daSRyan Leavengood			// Not used right now
17644f919daSRyan Leavengood			fPackageFile->Seek(4, SEEK_CUR);
17744f919daSRyan Leavengood			parser_debug("FVer\n");
17878c00a4aSAxel Dörfler		} else if (!memcmp(buffer, "AFla", 5)) {
17944f919daSRyan Leavengood			// Not used right now TODO: Check what this tag is for
18044f919daSRyan Leavengood			fPackageFile->Seek(8, SEEK_CUR);
18144f919daSRyan Leavengood			parser_debug("AFla\n");
18278c00a4aSAxel Dörfler		} else if (!memcmp(buffer, "FSiz", 5)) {
18344f919daSRyan Leavengood			fPackageFile->Read(&fileSize, 8);
18444f919daSRyan Leavengood			swap_data(B_UINT64_TYPE, &fileSize, sizeof(uint64),
18544f919daSRyan Leavengood					B_SWAP_BENDIAN_TO_HOST);
18644f919daSRyan Leavengood			parser_debug("FSiz %llu\n", fileSize);
18778c00a4aSAxel Dörfler		} else if (!memcmp(buffer, "COff", 5)) {
18844f919daSRyan Leavengood			fPackageFile->Read(&infoOffset, 8);
18944f919daSRyan Leavengood			swap_data(B_UINT64_TYPE, &infoOffset, sizeof(uint64),
19044f919daSRyan Leavengood					B_SWAP_BENDIAN_TO_HOST);
19144f919daSRyan Leavengood			parser_debug("COff %llu\n", infoOffset);
19278c00a4aSAxel Dörfler		} else if (!memcmp(buffer, "AOff", 5)) {
19344f919daSRyan Leavengood			fPackageFile->Read(&groupsOffset, 8);
19444f919daSRyan Leavengood			swap_data(B_UINT64_TYPE, &groupsOffset, sizeof(uint64),
19544f919daSRyan Leavengood					B_SWAP_BENDIAN_TO_HOST);
19644f919daSRyan Leavengood			parser_debug("AOff %llu\n", groupsOffset);
19778c00a4aSAxel Dörfler		} else if (!memcmp(buffer, padding, 7)) {
19844f919daSRyan Leavengood			// This means the end of this section - we should move to the
19944f919daSRyan Leavengood			// groups section.
20044f919daSRyan Leavengood			if (groupsOffset) {
20144f919daSRyan Leavengood				fPackageFile->Seek(groupsOffset, SEEK_SET);
20244f919daSRyan Leavengood			}
20344f919daSRyan Leavengood			parser_debug("End!\n");
20444f919daSRyan Leavengood			break;
20578c00a4aSAxel Dörfler		} else {
2060064d324SJérôme Duval			RETURN_AND_SET_STATUS(B_ERROR);
20744f919daSRyan Leavengood		}
20844f919daSRyan Leavengood	}
20944f919daSRyan Leavengood
21044f919daSRyan Leavengood	fPackageFile->Read(buffer, 7);
21144f919daSRyan Leavengood	if (memcmp(buffer, "PkgA", 5) || !groupsOffset || !infoOffset) {
2120064d324SJérôme Duval		RETURN_AND_SET_STATUS(B_ERROR);
21344f919daSRyan Leavengood	}
21478c00a4aSAxel Dörfler
21544f919daSRyan Leavengood	// Section header identifying constant byte sequences:
21644f919daSRyan Leavengood	const char groupsMarker[7] = { 0, 0, 0, 1, 0, 0, 4 };
21744f919daSRyan Leavengood	const char idMarker[7] = { 0, 0, 0, 2, 0, 0, 4 };
21844f919daSRyan Leavengood	const char pathMarker[7] = { 0, 0, 0, 3, 0, 0, 4 };
21944f919daSRyan Leavengood	const char upathMarker[7] = { 0, 0, 0, 4, 0, 0, 4 };
22044f919daSRyan Leavengood	const char licenseMarker[7] = { 0, 0, 0, 18, 0, 0, 4 };
22144f919daSRyan Leavengood	const char descMarker[7] = { 0, 0, 0, 5, 0, 0, 2 };
22244f919daSRyan Leavengood	const char helpMarker[7] = { 0, 0, 0, 10, 0, 0, 3 };
22344f919daSRyan Leavengood
22444f919daSRyan Leavengood	const char splashScreenMarker[7] = { 0, 0, 0, 8, 0, 0, 3 };
22544f919daSRyan Leavengood	const char disclaimerMarker[7] = { 0, 0, 0, 7, 0, 0, 3 };
22678c00a4aSAxel Dörfler
22744f919daSRyan Leavengood	const char nameMarker[7] = { 0, 0, 0, 13, 0, 0, 2 };
22844f919daSRyan Leavengood	const char versionMarker[7] = { 0, 0, 0, 14, 0, 0, 2 };
22944f919daSRyan Leavengood	const char devMarker[7] = { 0, 0, 0, 15, 0, 0, 2 };
23044f919daSRyan Leavengood	const char shortDescMarker[7] = { 0, 0, 0, 17, 0, 0, 2 };
23144f919daSRyan Leavengood
23244f919daSRyan Leavengood	int8 section = P_GROUPS_SECTION, installDirectoryFlag = 0;
23344f919daSRyan Leavengood
23444f919daSRyan Leavengood	pkg_profile group;
23544f919daSRyan Leavengood	BList groups(3), userPaths(3), systemPaths(10);
23644f919daSRyan Leavengood	bool groupStarted = false;
23744f919daSRyan Leavengood	parser_debug("Package Info reached!\n");
23844f919daSRyan Leavengood	// TODO: Maybe checking whether the needed number of bytes are read
23944f919daSRyan Leavengood	//	everytime would be a good idea
24044f919daSRyan Leavengood
24144f919daSRyan Leavengood	// Parse the package info section
24278c00a4aSAxel Dörfler	while (true) {
24344f919daSRyan Leavengood		bytesRead = fPackageFile->Read(buffer, 7);
24444f919daSRyan Leavengood		if (bytesRead != 7) {
24544f919daSRyan Leavengood			parser_debug("EOF!\n");
24644f919daSRyan Leavengood			break;
24744f919daSRyan Leavengood		}
24844f919daSRyan Leavengood
24944f919daSRyan Leavengood		if (!memcmp(buffer, groupsMarker, 7)) {
25044f919daSRyan Leavengood			section = P_GROUPS_SECTION;
25144f919daSRyan Leavengood			parser_debug("Got to Groups section\n");
25244f919daSRyan Leavengood			continue;
25378c00a4aSAxel Dörfler		} else if (!memcmp(buffer, pathMarker, 7)) {
25444f919daSRyan Leavengood			section = P_PATH_SECTION;
25544f919daSRyan Leavengood			parser_debug("Got to System Paths\n");
25644f919daSRyan Leavengood			continue;
25778c00a4aSAxel Dörfler		} else if (!memcmp(buffer, upathMarker, 7)) {
25844f919daSRyan Leavengood			section = P_USER_PATH_SECTION;
25944f919daSRyan Leavengood			parser_debug("Got to User Paths\n");
26044f919daSRyan Leavengood			continue;
26178c00a4aSAxel Dörfler		} else if (!memcmp(buffer, licenseMarker, 7)) {
26244f919daSRyan Leavengood			section = P_LICENSE_SECTION;
26344f919daSRyan Leavengood			parser_debug("Got to License\n");
26444f919daSRyan Leavengood			continue;
26578c00a4aSAxel Dörfler			// After this, non sectioned tags follow
26678c00a4aSAxel Dörfler		} else if (!memcmp(buffer, disclaimerMarker, 7)) {
26744f919daSRyan Leavengood			uint64 length;
26844f919daSRyan Leavengood			fPackageFile->Read(&length, 8);
26978c00a4aSAxel Dörfler			swap_data(B_UINT64_TYPE, &length, sizeof(uint64),
27078c00a4aSAxel Dörfler				B_SWAP_BENDIAN_TO_HOST);
27144f919daSRyan Leavengood
27244f919daSRyan Leavengood			uint64 original;
27344f919daSRyan Leavengood			if (fPackageFile->Read(&original, 8) != 8) {
2740064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
27544f919daSRyan Leavengood			}
27678c00a4aSAxel Dörfler			swap_data(B_UINT64_TYPE, &original, sizeof(uint64),
27778c00a4aSAxel Dörfler				B_SWAP_BENDIAN_TO_HOST);
27844f919daSRyan Leavengood
27944f919daSRyan Leavengood			fPackageFile->Seek(4, SEEK_CUR);
28044f919daSRyan Leavengood
28144f919daSRyan Leavengood			uint8 *compressed = new uint8[length];
28278c00a4aSAxel Dörfler			if (fPackageFile->Read(compressed, length)
28378c00a4aSAxel Dörfler					!= static_cast<int64>(length)) {
2843b49d994SMurai Takashi				delete[] compressed;
2850064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
28644f919daSRyan Leavengood			}
28778c00a4aSAxel Dörfler
28844f919daSRyan Leavengood			uint8 *disclaimer = new uint8[original + 1];
28978c00a4aSAxel Dörfler			status_t ret = inflate_data(compressed, length, disclaimer,
29078c00a4aSAxel Dörfler				original);
29144f919daSRyan Leavengood			disclaimer[original] = 0;
2923b49d994SMurai Takashi			delete[] compressed;
29344f919daSRyan Leavengood			if (ret != B_OK) {
2943b49d994SMurai Takashi				delete[] disclaimer;
2950064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
29644f919daSRyan Leavengood			}
29744f919daSRyan Leavengood
29844f919daSRyan Leavengood			fDisclaimer = (char *)disclaimer;
2993b49d994SMurai Takashi			delete[] disclaimer;
30044f919daSRyan Leavengood
3017974d3dcSStephan Aßmus			continue;
30278c00a4aSAxel Dörfler		} else if (!memcmp(buffer, splashScreenMarker, 7)) {
30344f919daSRyan Leavengood			uint64 length;
30444f919daSRyan Leavengood			fPackageFile->Read(&length, 8);
30578c00a4aSAxel Dörfler			swap_data(B_UINT64_TYPE, &length, sizeof(uint64),
30678c00a4aSAxel Dörfler				B_SWAP_BENDIAN_TO_HOST);
30744f919daSRyan Leavengood
30844f919daSRyan Leavengood			uint64 original;
30944f919daSRyan Leavengood			if (fPackageFile->Read(&original, 8) != 8) {
3100064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
31144f919daSRyan Leavengood			}
31278c00a4aSAxel Dörfler			swap_data(B_UINT64_TYPE, &original, sizeof(uint64),
31378c00a4aSAxel Dörfler				B_SWAP_BENDIAN_TO_HOST);
31444f919daSRyan Leavengood
31544f919daSRyan Leavengood			fPackageFile->Seek(4, SEEK_CUR);
31644f919daSRyan Leavengood
31744f919daSRyan Leavengood			uint8 *compressed = new uint8[length];
31878c00a4aSAxel Dörfler			if (fPackageFile->Read(compressed, length)
31978c00a4aSAxel Dörfler					!= static_cast<int64>(length)) {
3203b49d994SMurai Takashi				delete[] compressed;
3210064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
32244f919daSRyan Leavengood			}
3237974d3dcSStephan Aßmus
32444f919daSRyan Leavengood			fImage.SetSize(original);
3257974d3dcSStephan Aßmus			status_t ret = inflate_data(compressed, length,
32678c00a4aSAxel Dörfler				static_cast<uint8 *>(const_cast<void *>(fImage.Buffer())),
32778c00a4aSAxel Dörfler				original);
3283b49d994SMurai Takashi			delete[] compressed;
32944f919daSRyan Leavengood			if (ret != B_OK) {
3300064d324SJérôme Duval				RETURN_AND_SET_STATUS(B_ERROR);
33144f919daSRyan Leavengood			}
33244f919daSRyan Leavengood			fHasImage = true;
33344f919daSRyan Leavengood			continue;
33444f919daSRyan Leavengood		}
33544f919daSRyan Leavengood
33644f919daSRyan Leavengood		switch (section) {
33744f919daSRyan Leavengood			case P_PATH_SECTION:
33844f919daSRyan Leavengood			{
33944f919daSRyan Leavengood				if (!memcmp(buffer, "DPat", 5)) {
34044f919daSRyan Leavengood					parser_debug("DPat\n");
34144f919daSRyan Leavengood					continue;
34278c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "FDst", 5)) {
34344f919daSRyan Leavengood					parser_debug("FDst - ");
34444f919daSRyan Leavengood					directory_which dir;
34544f919daSRyan Leavengood					if (fPackageFile->Read(&dir, 4) != 4) {
3460064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
34744f919daSRyan Leavengood					}
34878c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &dir, sizeof(uint32),
34978c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
35044f919daSRyan Leavengood					BPath *path = new BPath();
35144f919daSRyan Leavengood					status_t ret = find_directory(dir, path);
35244f919daSRyan Leavengood					if (ret != B_OK) {
353e3e5e006SPhilippe Saint-Pierre						delete path;
3540064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
35544f919daSRyan Leavengood					}
35644f919daSRyan Leavengood
35744f919daSRyan Leavengood					parser_debug("%s\n", path->Path());
35844f919daSRyan Leavengood
35944f919daSRyan Leavengood					systemPaths.AddItem(path);
36078c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "PaNa", 5)) {
36144f919daSRyan Leavengood					parser_debug("PaNa\n");
36244f919daSRyan Leavengood					if (fPackageFile->Read(&length, 4) != 4) {
3630064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
36444f919daSRyan Leavengood					}
36578c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &length, sizeof(uint32),
36678c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
36778c00a4aSAxel Dörfler					// Since its a default, system path, we can ignore the path
36878c00a4aSAxel Dörfler					// name - all information needed is beside the FDst tag.
36944f919daSRyan Leavengood					fPackageFile->Seek(length, SEEK_CUR);
37078c00a4aSAxel Dörfler				} else if (!memcmp(buffer, padding, 7)) {
37144f919daSRyan Leavengood					parser_debug("Padding!\n");
37244f919daSRyan Leavengood					continue;
37378c00a4aSAxel Dörfler				} else {
3740064d324SJérôme Duval					RETURN_AND_SET_STATUS(B_ERROR);
37544f919daSRyan Leavengood				}
37644f919daSRyan Leavengood				break;
37744f919daSRyan Leavengood			}
37844f919daSRyan Leavengood
37944f919daSRyan Leavengood			case P_GROUPS_SECTION:
38044f919daSRyan Leavengood			{
38144f919daSRyan Leavengood				if (!memcmp(buffer, "IGrp", 5)) {
38244f919daSRyan Leavengood					// Creata a new group
38344f919daSRyan Leavengood					groupStarted = true;
38444f919daSRyan Leavengood					group = pkg_profile();
38544f919daSRyan Leavengood					parser_debug("IGrp\n");
38678c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "GrpN", 5)) {
38744f919daSRyan Leavengood					if (!groupStarted) {
3880064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
38944f919daSRyan Leavengood					}
39078c00a4aSAxel Dörfler
39144f919daSRyan Leavengood					parser_debug("GrpN\n");
39244f919daSRyan Leavengood					fPackageFile->Read(&length, 4);
39378c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &length, sizeof(uint32),
39478c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
39544f919daSRyan Leavengood
39644f919daSRyan Leavengood					char *name = new char[length + 1];
39744f919daSRyan Leavengood					fPackageFile->Read(name, length);
39844f919daSRyan Leavengood					name[length] = 0;
39944f919daSRyan Leavengood					group.name = name;
4003b49d994SMurai Takashi					delete[] name;
40178c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "GrpD", 5)) {
40244f919daSRyan Leavengood					if (!groupStarted) {
4030064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
40444f919daSRyan Leavengood					}
40578c00a4aSAxel Dörfler
40644f919daSRyan Leavengood					parser_debug("GrpD\n");
40744f919daSRyan Leavengood					fPackageFile->Read(&length, 4);
40878c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &length, sizeof(uint32),
40978c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
41044f919daSRyan Leavengood
41144f919daSRyan Leavengood					char *desc = new char[length + 1];
41244f919daSRyan Leavengood					fPackageFile->Read(desc, length);
41344f919daSRyan Leavengood					desc[length] = 0;
41444f919daSRyan Leavengood					group.description = desc;
4153b49d994SMurai Takashi					delete[] desc;
41678c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "GrHt", 5)) {
41744f919daSRyan Leavengood					if (!groupStarted) {
4180064d324SJérôme Duval						RETURN_AND_SET_STATUS(B_ERROR);
41944f919daSRyan Leavengood					}
42044f919daSRyan Leavengood
42144f919daSRyan Leavengood					parser_debug("GrHt\n");
42244f919daSRyan Leavengood					// For now, we don't need group help
42344f919daSRyan Leavengood					fPackageFile->Read(&length, 4);
42478c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &length, sizeof(uint32),
42578c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
42644f919daSRyan Leavengood					fPackageFile->Seek(length, SEEK_CUR);
42778c00a4aSAxel Dörfler				} else if (!memcmp(buffer, padding, 5)) {
42844f919daSRyan Leavengood					if (!groupStarted) {
42944f919daSRyan Leavengood						parser_debug("No group - padding!\n");
43044f919daSRyan Leavengood						continue;
43144f919daSRyan Leavengood					}
43244f919daSRyan Leavengood
43344f919daSRyan Leavengood					fProfiles.AddItem(new pkg_profile(group));
4347974d3dcSStephan Aßmus					parser_debug("Group added: %s %s\n", group.name.String(),
43578c00a4aSAxel Dörfler						group.description.String());
43678c00a4aSAxel Dörfler
43744f919daSRyan Leavengood					groupStarted = false;
43878c00a4aSAxel Dörfler				} else if (!memcmp(buffer, "GrId", 5)) {
43944f919daSRyan Leavengood					uint32 id;
44044f919daSRyan Leavengood					fPackageFile->Read(&id, 4);
44178c00a4aSAxel Dörfler					swap_data(B_UINT32_TYPE, &id, sizeof(uint32),
44278c00a4aSAxel Dörfler						B_SWAP_BENDIAN_TO_HOST);
44344f919daSRyan Leavengood
44444f919daSRyan Leavengood					parser_debug("GrId\n");
44578c00a4aSAxel Dörfler
446