1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/***************************************************************/
/* perk: PE Resource Kit */
/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.PERK. */
/***************************************************************/
#include <perk/perk.h>
#include "perk_driver_impl.h"
#include "perk_errinfo_impl.h"
#include "perk_ar_impl.h"
int pe_ar_list_members(const struct pe_archive_meta *, const char **);
static int pe_cmd_ar_perform_unit_actions(
const struct pe_driver_ctx * dctx,
const char * arname,
const char ** members,
uint64_t action)
{
struct pe_unit_ctx * arctx = 0;
int (*pe_ar_fn)(const struct pe_archive_meta *,const char **);
if (action == PERK_DRIVER_AR_LIST_MEMBERS) {
pe_ar_fn = pe_ar_list_members;
} else if (action == PERK_DRIVER_AR_PRINT_MEMBERS) {
pe_ar_fn = pe_ar_print_members;
} else {
return 0;
}
if (pe_lib_get_unit_ctx(dctx,arname,&arctx) < 0)
return PERK_NESTED_ERROR(dctx);
if (arctx->armeta == 0)
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_NON_ARCHIVE_IMAGE);
if (pe_ar_fn(arctx->armeta,members) < 0) {
pe_lib_free_unit_ctx(arctx);
return PERK_NESTED_ERROR(dctx);
}
pe_lib_free_unit_ctx(arctx);
return 0;
}
static int pe_cmd_ar_verify_cmdline(
const struct pe_driver_ctx * dctx,
uint64_t flags,
const char * posname,
const char * arname,
const char ** members)
{
uint64_t action;
uint64_t poscmd;
uint64_t vercmd;
action = (flags & AR_ACTION_MASK);
poscmd = (flags & AR_POSNAME_MASK);
vercmd = (flags & PERK_DRIVER_VERSION);
if (vercmd && !posname && !arname && !members)
return 0;
switch (action) {
case 0:
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_MISSING_ACTION);
case PERK_DRIVER_AR_LIST_MEMBERS:
case PERK_DRIVER_AR_DELETE_MEMBERS:
case PERK_DRIVER_AR_APPEND_MEMBERS:
case PERK_DRIVER_AR_EXTRACT_MEMBERS:
case PERK_DRIVER_AR_PRINT_MEMBERS:
if (poscmd || posname)
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_INVALID_ANCHORS);
break;
case AR_UPDATE_MASK:
case PERK_DRIVER_AR_REPLACE_MEMBERS:
case PERK_DRIVER_AR_MOVE_MEMBERS:
switch (poscmd) {
case 0:
if (posname)
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_MISSING_ANCHOR);
break;
case PERK_DRIVER_AR_POSITION_AFTER:
case PERK_DRIVER_AR_POSITION_BEFORE:
if (!posname)
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_NULL_POSNAME);
break;
default:
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_MULTIPLE_ANCHORS);
}
default:
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_MULTIPLE_ACTIONS);
}
if (!arname)
return PERK_CUSTOM_ERROR(dctx,
PERK_ERR_AR_NULL_ARNAME);
return 0;
}
int pe_cmd_ar(
const struct pe_driver_ctx * dctx,
uint64_t flags,
const char * posname,
const char * arname,
const char ** members)
{
uint64_t action = (flags & AR_ACTION_MASK);
if (pe_cmd_ar_verify_cmdline(dctx,flags,posname,arname,members) < 0)
return PERK_NESTED_ERROR(dctx);
if (pe_cmd_ar_perform_unit_actions(dctx,arname,members,action) < 0)
return PERK_NESTED_ERROR(dctx);
return 0;
}
|