VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/checksum/manifest2.cpp@ 34418

Last change on this file since 34418 was 34418, checked in by vboxsync, 14 years ago

VBoxExtPAckHelperApp.cpp: More code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/* $Id: manifest2.cpp 34418 2010-11-26 17:25:58Z vboxsync $ */
2/** @file
3 * IPRT - Manifest, the core.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/manifest.h>
33
34#include <iprt/asm.h>
35#include <iprt/assert.h>
36#include <iprt/err.h>
37#include <iprt/mem.h>
38#include <iprt/string.h>
39#include <iprt/vfs.h>
40
41#include "internal/magics.h"
42
43
44/*******************************************************************************
45* Structures and Typedefs *
46*******************************************************************************/
47/**
48 * Manifest attribute.
49 *
50 * Used both for entries and manifest attributes.
51 */
52typedef struct RTMANIFESTATTR
53{
54 /** The string space core (szName). */
55 RTSTRSPACECORE StrCore;
56 /** The property value. */
57 char *pszValue;
58 /** The attribute type if applicable, RTMANIFEST_ATTR_UNKNOWN if not. */
59 uint32_t fType;
60 /** The normalized property name that StrCore::pszString points at. */
61 char szName[1];
62} RTMANIFESTATTR;
63/** Pointer to a manifest attribute. */
64typedef RTMANIFESTATTR *PRTMANIFESTATTR;
65
66
67/**
68 * Manifest entry.
69 */
70typedef struct RTMANIFESTENTRY
71{
72 /** The string space core (szName). */
73 RTSTRSPACECORE StrCore;
74 /** The entry attributes (hashes, checksums, size, etc) -
75 * RTMANIFESTATTR. */
76 RTSTRSPACE Attributes;
77 /** The normalized entry name that StrCore::pszString points at. */
78 char szName[1];
79} RTMANIFESTENTRY;
80/** Pointer to a manifest entry. */
81typedef RTMANIFESTENTRY *PRTMANIFESTENTRY;
82
83
84/**
85 * Manifest handle data.
86 */
87typedef struct RTMANIFESTINT
88{
89 /** Magic value (RTMANIFEST_MAGIC). */
90 uint32_t u32Magic;
91 /** The number of references to this manifest. */
92 uint32_t volatile cRefs;
93 /** Manifest attributes - RTMANIFESTATTR. */
94 RTSTRSPACE Attributes;
95 /** String space of the entries covered by this manifest -
96 * RTMANIFESTENTRY. */
97 RTSTRSPACE Entries;
98} RTMANIFESTINT;
99
100/** The value of RTMANIFESTINT::u32Magic. */
101#define RTMANIFEST_MAGIC UINT32_C(0x99998866)
102
103
104/**
105 * Creates an empty manifest.
106 *
107 * @returns IPRT status code.
108 * @param fFlags Flags, MBZ.
109 * @param phManifest Where to return the handle to the manifest.
110 */
111RTDECL(int) RTManifestCreate(uint32_t fFlags, PRTMANIFEST phManifest)
112{
113 AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
114 AssertPtr(phManifest);
115
116 RTMANIFESTINT *pThis = (RTMANIFESTINT *)RTMemAlloc(sizeof(*pThis));
117 if (!pThis)
118 return VERR_NO_MEMORY;
119
120 pThis->u32Magic = RTMANIFEST_MAGIC;
121 pThis->cRefs = 1;
122 pThis->Attributes = NULL;
123 pThis->Entries = NULL;
124
125 *phManifest = pThis;
126 return VINF_SUCCESS;
127}
128
129/**
130 * Retains a reference to the manifest handle.
131 *
132 * @returns The new reference count, UINT32_MAX if the handle is invalid.
133 * @param hManifest The handle to retain.
134 */
135RTDECL(uint32_t) RTManifestRetain(RTMANIFEST hManifest)
136{
137 RTMANIFESTINT *pThis = hManifest;
138 AssertPtrReturn(pThis, UINT32_MAX);
139 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
140
141 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
142 Assert(cRefs > 1 && cRefs < _1M);
143
144 return cRefs;
145}
146
147
148/**
149 * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTATTR.}
150 */
151static DECLCALLBACK(int) rtManifestDestroyAttribute(PRTSTRSPACECORE pStr, void *pvUser)
152{
153 PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
154 RTStrFree(pAttr->pszValue);
155 pAttr->pszValue = NULL;
156 RTMemFree(pAttr);
157 return 0;
158}
159
160
161/**
162 * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTENTRY.}
163 */
164static DECLCALLBACK(int) rtManifestDestroyEntry(PRTSTRSPACECORE pStr, void *pvUser)
165{
166 PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
167 RTStrSpaceDestroy(&pEntry->Attributes, rtManifestDestroyAttribute, pvUser);
168 RTMemFree(pEntry);
169 return 0;
170}
171
172
173/**
174 * Releases a reference to the manifest handle.
175 *
176 * @returns The new reference count, 0 if free. UINT32_MAX is returned if the
177 * handle is invalid.
178 * @param hManifest The handle to release.
179 * NIL is quietly ignored (returns 0).
180 */
181RTDECL(uint32_t) RTManifestRelease(RTMANIFEST hManifest)
182{
183 RTMANIFESTINT *pThis = hManifest;
184 if (pThis == NIL_RTMANIFEST)
185 return 0;
186 AssertPtrReturn(pThis, UINT32_MAX);
187 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
188
189 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
190 Assert(cRefs < _1M);
191 if (!cRefs)
192 {
193 ASMAtomicWriteU32(&pThis->u32Magic, ~RTMANIFEST_MAGIC);
194 RTStrSpaceDestroy(&pThis->Attributes, rtManifestDestroyAttribute, pThis);
195 RTStrSpaceDestroy(&pThis->Entries, rtManifestDestroyEntry, pThis);
196 RTMemFree(pThis);
197 }
198
199 return cRefs;
200}
201
202
203/**
204 * Creates a duplicate of the specified manifest.
205 *
206 * @returns IPRT status code
207 * @param hManifestSrc The manifest to clone.
208 * @param phManifestDst Where to store the handle to the duplicate.
209 */
210RTDECL(int) RTManifestDup(RTMANIFEST hManifestSrc, PRTMANIFEST phManifestDst)
211{
212 RTMANIFESTINT *pThis = hManifestSrc;
213 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
214 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
215 AssertPtr(phManifestDst);
216
217
218 /** @todo implement cloning. */
219
220 return VERR_NOT_IMPLEMENTED;
221}
222
223
224RTDECL(int) RTManifestEqualsEx(RTMANIFEST hManifest1, RTMANIFEST hManifest2, const char * const *papszIgnoreEntries,
225 const char * const *papszIgnoreAttr, char *pszEntry, size_t cbEntry)
226{
227 /*
228 * Validate input.
229 */
230 AssertPtrNullReturn(pszEntry, VERR_INVALID_POINTER);
231 if (pszEntry && cbEntry)
232 *pszEntry = '\0';
233 RTMANIFESTINT *pThis1 = hManifest1;
234 RTMANIFESTINT *pThis2 = hManifest1;
235 if (pThis1 != NIL_RTMANIFEST)
236 {
237 AssertPtrReturn(pThis1, VERR_INVALID_HANDLE);
238 AssertReturn(pThis1->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
239 }
240 if (pThis2 != NIL_RTMANIFEST)
241 {
242 AssertPtrReturn(pThis2, VERR_INVALID_HANDLE);
243 AssertReturn(pThis2->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
244 }
245
246 /*
247 * The simple cases.
248 */
249 if (pThis1 == pThis2)
250 return VINF_SUCCESS;
251 if (pThis1 == NIL_RTMANIFEST || pThis2 == NIL_RTMANIFEST)
252 return VERR_NOT_EQUAL;
253
254 /*
255 *
256 */
257
258
259 /** @todo implement comparing. */
260
261 return VERR_NOT_IMPLEMENTED;
262}
263
264
265RTDECL(int) RTManifestEquals(RTMANIFEST hManifest1, RTMANIFEST hManifest2)
266{
267 return RTManifestEqualsEx(hManifest1, hManifest2, NULL /*papszIgnoreEntries*/, NULL /*papszIgnoreAttrs*/, NULL, 0);
268}
269
270
271/**
272 * Worker common to RTManifestSetAttr and RTManifestEntrySetAttr.
273 *
274 * @returns IPRT status code.
275 * @param pAttributes The attribute container.
276 * @param pszAttr The name of the attribute to add.
277 * @param pszValue The value string.
278 * @param fType The attribute type type.
279 */
280static int rtManifestSetAttrWorker(PRTSTRSPACE pAttributes, const char *pszAttr, const char *pszValue, uint32_t fType)
281{
282 char *pszValueCopy;
283 int rc = RTStrDupEx(&pszValueCopy, pszValue);
284 if (RT_FAILURE(rc))
285 return rc;
286
287 /*
288 * Does the attribute exist already?
289 */
290 AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
291 PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(pAttributes, pszAttr);
292 if (pAttr)
293 {
294 RTStrFree(pAttr->pszValue);
295 pAttr->pszValue = pszValueCopy;
296 pAttr->fType = fType;
297 }
298 else
299 {
300 size_t cbName = strlen(pszAttr) + 1;
301 pAttr = (PRTMANIFESTATTR)RTMemAllocVar(RT_OFFSETOF(RTMANIFESTATTR, szName[cbName]));
302 if (!pAttr)
303 {
304 RTStrFree(pszValueCopy);
305 return VERR_NO_MEMORY;
306 }
307 memcpy(pAttr->szName, pszAttr, cbName);
308 pAttr->StrCore.pszString = pAttr->szName;
309 pAttr->StrCore.cchString = cbName - 1;
310 pAttr->pszValue = pszValueCopy;
311 pAttr->fType = fType;
312 if (RT_UNLIKELY(!RTStrSpaceInsert(pAttributes, &pAttr->StrCore)))
313 {
314 AssertFailed();
315 RTStrFree(pszValueCopy);
316 RTMemFree(pAttr);
317 return VERR_INTERNAL_ERROR_4;
318 }
319 }
320
321 return VINF_SUCCESS;
322}
323
324
325/**
326 * Sets a manifest attribute.
327 *
328 * @returns IPRT status code.
329 * @param hManifest The manifest handle.
330 * @param pszAttr The attribute name. If this already exists,
331 * its value will be replaced.
332 * @param pszValue The value string.
333 * @param fType The attribute type, pass
334 * RTMANIFEST_ATTR_UNKNOWN if not known.
335 */
336RTDECL(int) RTManifestSetAttr(RTMANIFEST hManifest, const char *pszAttr, const char *pszValue, uint32_t fType)
337{
338 RTMANIFESTINT *pThis = hManifest;
339 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
340 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
341 AssertPtr(pszAttr);
342 AssertPtr(pszValue);
343 AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
344
345 return rtManifestSetAttrWorker(&pThis->Attributes, pszAttr, pszValue, fType);
346}
347
348
349/**
350 * Worker common to RTManifestUnsetAttr and RTManifestEntryUnsetAttr.
351 *
352 * @returns IPRT status code.
353 * @param pAttributes The attribute container.
354 * @param pszAttr The name of the attribute to remove.
355 */
356static int rtManifestUnsetAttrWorker(PRTSTRSPACE pAttributes, const char *pszAttr)
357{
358 PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(pAttributes, pszAttr);
359 if (!pStrCore)
360 return VWRN_NOT_FOUND;
361 rtManifestDestroyAttribute(pStrCore, NULL);
362 return VINF_SUCCESS;
363}
364
365
366/**
367 * Unsets (removes) a manifest attribute if it exists.
368 *
369 * @returns IPRT status code.
370 * @retval VWRN_NOT_FOUND if not found.
371 *
372 * @param hManifest The manifest handle.
373 * @param pszAttr The attribute name.
374 */
375RTDECL(int) RTManifestUnsetAttr(RTMANIFEST hManifest, const char *pszAttr)
376{
377 RTMANIFESTINT *pThis = hManifest;
378 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
379 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
380 AssertPtr(pszAttr);
381
382 return rtManifestUnsetAttrWorker(&pThis->Attributes, pszAttr);
383}
384
385
386/**
387 * Validates the name entry.
388 *
389 * @returns IPRT status code.
390 * @param pszEntry The entry name to validate.
391 * @param pfNeedNormalization Where to return whether it needs normalization
392 * or not. Optional.
393 * @param pcchEntry Where to return the length. Optional.
394 */
395static int rtManifestValidateNameEntry(const char *pszEntry, bool *pfNeedNormalization, size_t *pcchEntry)
396{
397 int rc;
398 bool fNeedNormalization = false;
399 const char *pszCur = pszEntry;
400
401 for (;;)
402 {
403 RTUNICP uc;
404 rc = RTStrGetCpEx(&pszCur, &uc);
405 if (RT_FAILURE(rc))
406 break;
407 if (!uc)
408 break;
409 if (uc == '\\')
410 fNeedNormalization = true;
411 else if (uc < 32 || uc == ':' || uc == '(' || uc == ')')
412 {
413 rc = VERR_INVALID_NAME;
414 break;
415 }
416 }
417
418 if (pfNeedNormalization)
419 *pfNeedNormalization = fNeedNormalization;
420 if (pcchEntry)
421 *pcchEntry = pszCur - pszEntry - 1;
422 return rc;
423}
424
425
426/**
427 * Normalizes a entry name.
428 *
429 * @param pszEntry The entry name to normalize.
430 */
431static void rtManifestNormalizeEntry(char *pszEntry)
432{
433 char ch;
434 while ((ch = *pszEntry))
435 {
436 if (ch == '\\')
437 *pszEntry = '/';
438 pszEntry++;
439 }
440}
441
442
443/**
444 * Gets an entry.
445 *
446 * @returns IPRT status code.
447 * @param pThis The manifest to work with.
448 * @param pszEntry The entry name.
449 * @param fNeedNormalization Whether rtManifestValidateNameEntry said it
450 * needed normalization.
451 * @param cchEntry The length of the name.
452 * @param ppEntry Where to return the entry pointer on success.
453 */
454static int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
455 PRTMANIFESTENTRY *ppEntry)
456{
457 PRTMANIFESTENTRY pEntry;
458
459 AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
460 if (!fNeedNormalization)
461 pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
462 else
463 {
464 char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
465 if (RT_UNLIKELY(!pszCopy))
466 return VERR_NO_TMP_MEMORY;
467 memcpy(pszCopy, pszEntry, cchEntry + 1);
468 rtManifestNormalizeEntry(pszCopy);
469
470 pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
471 RTMemTmpFree(pszCopy);
472 }
473
474 *ppEntry = pEntry;
475 return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND;
476}
477
478
479/**
480 * Sets an attribute of a manifest entry.
481 *
482 * @returns IPRT status code.
483 * @param hManifest The manifest handle.
484 * @param pszEntry The entry name. This will automatically be
485 * added if there was no previous call to
486 * RTManifestEntryAdd for this name. See
487 * RTManifestEntryAdd for the entry name rules.
488 * @param pszAttr The attribute name. If this already exists,
489 * its value will be replaced.
490 * @param pszValue The value string.
491 * @param fType The attribute type, pass
492 * RTMANIFEST_ATTR_UNKNOWN if not known.
493 */
494RTDECL(int) RTManifestEntrySetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr,
495 const char *pszValue, uint32_t fType)
496{
497 RTMANIFESTINT *pThis = hManifest;
498 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
499 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
500 AssertPtr(pszEntry);
501 AssertPtr(pszAttr);
502 AssertPtr(pszValue);
503 AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
504
505 bool fNeedNormalization;
506 size_t cchEntry;
507 int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
508 AssertRCReturn(rc, rc);
509
510 /*
511 * Resolve the entry, adding one if necessary.
512 */
513 PRTMANIFESTENTRY pEntry;
514 rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
515 if (rc == VERR_NOT_FOUND)
516 {
517 pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
518 if (!pEntry)
519 return VERR_NO_MEMORY;
520
521 pEntry->StrCore.cchString = cchEntry;
522 pEntry->StrCore.pszString = pEntry->szName;
523 pEntry->Attributes = NULL;
524 memcpy(pEntry->szName, pszEntry, cchEntry + 1);
525 if (fNeedNormalization)
526 rtManifestNormalizeEntry(pEntry->szName);
527
528 if (!RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
529 {
530 RTMemFree(pEntry);
531 return VERR_INTERNAL_ERROR_4;
532 }
533 }
534 else if (RT_FAILURE(rc))
535 return rc;
536
537 return rtManifestSetAttrWorker(&pEntry->Attributes, pszAttr, pszValue, fType);
538}
539
540
541/**
542 * Unsets (removes) an attribute of a manifest entry if they both exist.
543 *
544 * @returns IPRT status code.
545 * @retval VWRN_NOT_FOUND if not found.
546 *
547 * @param hManifest The manifest handle.
548 * @param pszEntry The entry name.
549 * @param pszAttr The attribute name.
550 */
551RTDECL(int) RTManifestEntryUnsetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr)
552{
553 RTMANIFESTINT *pThis = hManifest;
554 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
555 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
556 AssertPtr(pszEntry);
557 AssertPtr(pszAttr);
558
559 bool fNeedNormalization;
560 size_t cchEntry;
561 int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
562 AssertRCReturn(rc, rc);
563
564 /*
565 * Resolve the entry and hand it over to the worker.
566 */
567 PRTMANIFESTENTRY pEntry;
568 rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
569 if (RT_SUCCESS(rc))
570 rc = rtManifestUnsetAttrWorker(&pEntry->Attributes, pszAttr);
571 return rc;
572}
573
574
575/**
576 * Adds a new entry to a manifest.
577 *
578 * The entry name rules:
579 * - The entry name can contain any character defined by unicode, except
580 * control characters, ':', '(' and ')'. The exceptions are mainly there
581 * because of uncertainty around how various formats handles these.
582 * - It is considered case sensitive.
583 * - Forward (unix) and backward (dos) slashes are considered path
584 * separators and converted to forward slashes.
585 *
586 * @returns IPRT status code.
587 * @retval VWRN_ALREADY_EXISTS if the entry already exists.
588 *
589 * @param hManifest The manifest handle.
590 * @param pszEntry The entry name (UTF-8).
591 *
592 * @remarks Some manifest formats will not be able to store an entry without
593 * any attributes. So, this is just here in case it comes in handy
594 * when dealing with formats which can.
595 */
596RTDECL(int) RTManifestEntryAdd(RTMANIFEST hManifest, const char *pszEntry)
597{
598 RTMANIFESTINT *pThis = hManifest;
599 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
600 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
601 AssertPtr(pszEntry);
602
603 bool fNeedNormalization;
604 size_t cchEntry;
605 int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
606 AssertRCReturn(rc, rc);
607
608 /*
609 * Only add one if it does not already exist.
610 */
611 PRTMANIFESTENTRY pEntry;
612 rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
613 if (rc == VERR_NOT_FOUND)
614 {
615 pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
616 if (pEntry)
617 {
618 pEntry->StrCore.cchString = cchEntry;
619 pEntry->StrCore.pszString = pEntry->szName;
620 pEntry->Attributes = NULL;
621 memcpy(pEntry->szName, pszEntry, cchEntry + 1);
622 if (fNeedNormalization)
623 rtManifestNormalizeEntry(pEntry->szName);
624
625 if (RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
626 rc = VINF_SUCCESS;
627 else
628 {
629 RTMemFree(pEntry);
630 rc = VERR_INTERNAL_ERROR_4;
631 }
632 }
633 else
634 rc = VERR_NO_MEMORY;
635 }
636 else if (RT_SUCCESS(rc))
637 rc = VWRN_ALREADY_EXISTS;
638
639 return rc;
640}
641
642
643/**
644 * Removes an entry.
645 *
646 * @returns IPRT status code.
647 * @param hManifest The manifest handle.
648 * @param pszEntry The entry name.
649 */
650RTDECL(int) RTManifestEntryRemove(RTMANIFEST hManifest, const char *pszEntry)
651{
652 RTMANIFESTINT *pThis = hManifest;
653 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
654 AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
655 AssertPtr(pszEntry);
656
657 bool fNeedNormalization;
658 size_t cchEntry;
659 int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
660 AssertRCReturn(rc, rc);
661
662 /*
663 * Only add one if it does not already exist.
664 */
665 PRTMANIFESTENTRY pEntry;
666 rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
667 if (RT_SUCCESS(rc))
668 {
669 PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(&pThis->Entries, pEntry->StrCore.pszString);
670 AssertReturn(pStrCore, VERR_INTERNAL_ERROR_3);
671 rtManifestDestroyEntry(pStrCore, pThis);
672 }
673
674 return rc;
675}
676
677
678/**
679 * Reads in a "standard" manifest.
680 *
681 * This reads the format used by OVF, the distinfo in FreeBSD ports, and
682 * others.
683 *
684 * @returns IPRT status code.
685 * @param hManifest The handle to the manifest where to add the
686 * manifest that's read in.
687 * @param hVfsIos The I/O stream to read the manifest from.
688 */
689RTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
690{
691 return VERR_NOT_IMPLEMENTED;
692}
693
694
695/**
696 * Writes a "standard" manifest.
697 *
698 * This writes the format used by OVF, the distinfo in FreeBSD ports, and
699 * others.
700 *
701 * @returns IPRT status code.
702 * @param hManifest The handle to the manifest where to add the
703 * manifest that's read in.
704 * @param hVfsIos The I/O stream to read the manifest from.
705 */
706RTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
707{
708 return VERR_NOT_IMPLEMENTED;
709}
710
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette