Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
a5e4f3cc
Commit
a5e4f3cc
authored
Dec 01, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separate cpio logic from MagiskBoot
parent
a30777bd
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
251 additions
and
172 deletions
+251
-172
Android.mk
jni/Android.mk
+2
-1
cpio.h
jni/include/cpio.h
+57
-0
magiskboot.h
jni/magiskboot/magiskboot.h
+14
-0
ramdisk.c
jni/magiskboot/ramdisk.c
+146
-0
cpio.c
jni/utils/cpio.c
+32
-171
No files found.
jni/Android.mk
View file @
a5e4f3cc
...
@@ -100,12 +100,13 @@ LOCAL_SRC_FILES := \
...
@@ -100,12 +100,13 @@ LOCAL_SRC_FILES := \
magiskboot/bootimg.c \
magiskboot/bootimg.c \
magiskboot/hexpatch.c \
magiskboot/hexpatch.c \
magiskboot/compress.c \
magiskboot/compress.c \
magiskboot/cpio.c \
magiskboot/sha1.c \
magiskboot/sha1.c \
magiskboot/types.c \
magiskboot/types.c \
magiskboot/dtb.c \
magiskboot/dtb.c \
magiskboot/ramdisk.c \
utils/xwrap.c \
utils/xwrap.c \
utils/file.c \
utils/file.c \
utils/cpio.c \
utils/vector.c
utils/vector.c
LOCAL_CFLAGS := -DNO_SELINUX
LOCAL_CFLAGS := -DNO_SELINUX
...
...
jni/
magiskboot
/cpio.h
→
jni/
include
/cpio.h
View file @
a5e4f3cc
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
#include <stdint.h>
#include <stdint.h>
#include "vector.h"
typedef
struct
cpio_entry
{
typedef
struct
cpio_entry
{
// uint32_t ino;
// uint32_t ino;
uint32_t
mode
;
uint32_t
mode
;
...
@@ -39,18 +41,17 @@ typedef struct cpio_newc_header {
...
@@ -39,18 +41,17 @@ typedef struct cpio_newc_header {
char
check
[
8
];
char
check
[
8
];
}
cpio_newc_header
;
}
cpio_newc_header
;
typedef
enum
{
void
parse_cpio
(
const
char
*
filename
,
struct
vector
*
v
);
NONE
,
void
dump_cpio
(
const
char
*
filename
,
struct
vector
*
v
);
RM
,
void
cpio_vec_destroy
(
struct
vector
*
v
);
MKDIR
,
void
cpio_rm
(
int
recursive
,
const
char
*
entry
,
struct
vector
*
v
);
ADD
,
void
cpio_mkdir
(
mode_t
mode
,
const
char
*
entry
,
struct
vector
*
v
);
MV
,
void
cpio_add
(
mode_t
mode
,
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
);
EXTRACT
,
void
cpio_mv
(
struct
vector
*
v
,
const
char
*
from
,
const
char
*
to
);
TEST
,
void
cpio_test
(
struct
vector
*
v
);
PATCH
,
void
cpio_extract
(
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
);
BACKUP
,
void
cpio_backup
(
const
char
*
orig
,
const
char
*
sha1
,
struct
vector
*
v
);
RESTORE
,
int
cpio_restore
(
struct
vector
*
v
);
STOCKSHA1
void
cpio_stocksha1
(
struct
vector
*
v
);
}
command_t
;
#endif
#endif
jni/magiskboot/magiskboot.h
View file @
a5e4f3cc
...
@@ -32,4 +32,18 @@ size_t lz4_legacy(int mode, int fd, const void *buf, size_t size);
...
@@ -32,4 +32,18 @@ size_t lz4_legacy(int mode, int fd, const void *buf, size_t size);
long
long
comp
(
file_t
type
,
int
to
,
const
void
*
from
,
size_t
size
);
long
long
comp
(
file_t
type
,
int
to
,
const
void
*
from
,
size_t
size
);
long
long
decomp
(
file_t
type
,
int
to
,
const
void
*
from
,
size_t
size
);
long
long
decomp
(
file_t
type
,
int
to
,
const
void
*
from
,
size_t
size
);
typedef
enum
{
NONE
,
RM
,
MKDIR
,
ADD
,
MV
,
EXTRACT
,
TEST
,
PATCH
,
BACKUP
,
RESTORE
,
STOCKSHA1
}
command_t
;
#endif
#endif
jni/magiskboot/ramdisk.c
0 → 100644
View file @
a5e4f3cc
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include "magiskboot.h"
#include "cpio.h"
int
check_verity_pattern
(
const
char
*
s
)
{
int
pos
=
0
;
if
(
s
[
0
]
==
','
)
++
pos
;
if
(
strncmp
(
s
+
pos
,
"verify"
,
6
)
==
0
)
pos
+=
6
;
else
if
(
strncmp
(
s
+
pos
,
"avb"
,
3
)
==
0
)
pos
+=
3
;
else
return
-
1
;
if
(
s
[
pos
]
==
'='
)
{
while
(
s
[
pos
]
!=
'\0'
&&
s
[
pos
]
!=
' '
&&
s
[
pos
]
!=
'\n'
&&
s
[
pos
]
!=
','
)
++
pos
;
}
return
pos
;
}
int
check_encryption_pattern
(
const
char
*
s
)
{
const
char
*
encrypt_list
[]
=
{
"forceencrypt"
,
"forcefdeorfbe"
,
NULL
};
for
(
int
i
=
0
;
encrypt_list
[
i
];
++
i
)
{
int
len
=
strlen
(
encrypt_list
[
i
]);
if
(
strncmp
(
s
,
encrypt_list
[
i
],
len
)
==
0
)
return
len
;
}
return
-
1
;
}
void
cpio_patch
(
struct
vector
*
v
,
int
keepverity
,
int
keepforceencrypt
)
{
cpio_entry
*
f
;
int
skip
,
write
;
vec_for_each
(
v
,
f
)
{
if
(
!
keepverity
)
{
if
(
strstr
(
f
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
f
->
mode
))
{
write
=
0
;
for
(
int
read
=
0
;
read
<
f
->
filesize
;
++
write
,
++
read
)
{
if
((
skip
=
check_verity_pattern
(
f
->
data
+
read
))
>
0
)
{
fprintf
(
stderr
,
"Remove pattern [%.*s] in [%s]
\n
"
,
skip
,
f
->
data
+
read
,
f
->
filename
);
read
+=
skip
;
}
f
->
data
[
write
]
=
f
->
data
[
read
];
}
f
->
filesize
=
write
;
}
else
if
(
strcmp
(
f
->
filename
,
"verity_key"
)
==
0
)
{
fprintf
(
stderr
,
"Remove [verity_key]
\n
"
);
f
->
remove
=
1
;
}
}
if
(
!
keepforceencrypt
)
{
if
(
strstr
(
f
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
f
->
mode
))
{
write
=
0
;
for
(
int
read
=
0
;
read
<
f
->
filesize
;
++
write
,
++
read
)
{
if
((
skip
=
check_encryption_pattern
(
f
->
data
+
read
))
>
0
)
{
// assert(skip > 11)!
fprintf
(
stderr
,
"Replace pattern [%.*s] with [encryptable] in [%s]
\n
"
,
skip
,
f
->
data
+
read
,
f
->
filename
);
memcpy
(
f
->
data
+
write
,
"encryptable"
,
11
);
write
+=
11
;
read
+=
skip
;
}
f
->
data
[
write
]
=
f
->
data
[
read
];
}
f
->
filesize
=
write
;
}
}
}
}
int
cpio_commands
(
const
char
*
command
,
int
argc
,
char
*
argv
[])
{
int
recursive
=
0
,
ret
=
0
;
command_t
cmd
;
char
*
incpio
=
argv
[
0
];
++
argv
;
--
argc
;
if
(
strcmp
(
command
,
"test"
)
==
0
)
{
cmd
=
TEST
;
}
else
if
(
strcmp
(
command
,
"restore"
)
==
0
)
{
cmd
=
RESTORE
;
}
else
if
(
strcmp
(
command
,
"stocksha1"
)
==
0
)
{
cmd
=
STOCKSHA1
;
}
else
if
(
argc
>=
1
&&
strcmp
(
command
,
"backup"
)
==
0
)
{
cmd
=
BACKUP
;
}
else
if
(
argc
>
0
&&
strcmp
(
command
,
"rm"
)
==
0
)
{
cmd
=
RM
;
if
(
argc
==
2
&&
strcmp
(
argv
[
0
],
"-r"
)
==
0
)
{
recursive
=
1
;
++
argv
;
--
argc
;
}
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"mv"
)
==
0
)
{
cmd
=
MV
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"patch"
)
==
0
)
{
cmd
=
PATCH
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"extract"
)
==
0
)
{
cmd
=
EXTRACT
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"mkdir"
)
==
0
)
{
cmd
=
MKDIR
;
}
else
if
(
argc
==
3
&&
strcmp
(
command
,
"add"
)
==
0
)
{
cmd
=
ADD
;
}
else
{
cmd
=
NONE
;
}
struct
vector
v
;
vec_init
(
&
v
);
parse_cpio
(
incpio
,
&
v
);
switch
(
cmd
)
{
case
TEST
:
cpio_test
(
&
v
);
break
;
case
RESTORE
:
ret
=
cpio_restore
(
&
v
);
break
;
case
STOCKSHA1
:
cpio_stocksha1
(
&
v
);
return
0
;
case
BACKUP
:
cpio_backup
(
argv
[
0
],
argc
>
1
?
argv
[
1
]
:
NULL
,
&
v
);
case
RM
:
cpio_rm
(
recursive
,
argv
[
0
],
&
v
);
break
;
case
PATCH
:
cpio_patch
(
&
v
,
strcmp
(
argv
[
0
],
"true"
)
==
0
,
strcmp
(
argv
[
1
],
"true"
)
==
0
);
break
;
case
EXTRACT
:
cpio_extract
(
argv
[
0
],
argv
[
1
],
&
v
);
break
;
case
MKDIR
:
cpio_mkdir
(
strtoul
(
argv
[
0
],
NULL
,
8
),
argv
[
1
],
&
v
);
break
;
case
ADD
:
cpio_add
(
strtoul
(
argv
[
0
],
NULL
,
8
),
argv
[
1
],
argv
[
2
],
&
v
);
break
;
case
MV
:
cpio_mv
(
&
v
,
argv
[
0
],
argv
[
1
]);
break
;
case
NONE
:
return
1
;
}
dump_cpio
(
incpio
,
&
v
);
cpio_vec_destroy
(
&
v
);
exit
(
ret
);
}
jni/
magiskboot
/cpio.c
→
jni/
utils
/cpio.c
View file @
a5e4f3cc
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include "magiskboot.h"
#include "cpio.h"
#include "cpio.h"
#include "logging.h"
#include "logging.h"
#include "utils.h"
#include "utils.h"
...
@@ -49,7 +48,7 @@ static int cpio_cmp(const void *a, const void *b) {
...
@@ -49,7 +48,7 @@ static int cpio_cmp(const void *a, const void *b) {
}
}
// Parse cpio file to a vector of cpio_entry
// Parse cpio file to a vector of cpio_entry
static
void
parse_cpio
(
const
char
*
filename
,
struct
vector
*
v
)
{
void
parse_cpio
(
const
char
*
filename
,
struct
vector
*
v
)
{
fprintf
(
stderr
,
"Loading cpio: [%s]
\n\n
"
,
filename
);
fprintf
(
stderr
,
"Loading cpio: [%s]
\n\n
"
,
filename
);
int
fd
=
xopen
(
filename
,
O_RDONLY
);
int
fd
=
xopen
(
filename
,
O_RDONLY
);
cpio_newc_header
header
;
cpio_newc_header
header
;
...
@@ -90,7 +89,7 @@ static void parse_cpio(const char *filename, struct vector *v) {
...
@@ -90,7 +89,7 @@ static void parse_cpio(const char *filename, struct vector *v) {
close
(
fd
);
close
(
fd
);
}
}
static
void
dump_cpio
(
const
char
*
filename
,
struct
vector
*
v
)
{
void
dump_cpio
(
const
char
*
filename
,
struct
vector
*
v
)
{
fprintf
(
stderr
,
"
\n
Dump cpio: [%s]
\n\n
"
,
filename
);
fprintf
(
stderr
,
"
\n
Dump cpio: [%s]
\n\n
"
,
filename
);
int
fd
=
creat
(
filename
,
0644
);
int
fd
=
creat
(
filename
,
0644
);
unsigned
inode
=
300000
;
unsigned
inode
=
300000
;
...
@@ -131,7 +130,7 @@ static void dump_cpio(const char *filename, struct vector *v) {
...
@@ -131,7 +130,7 @@ static void dump_cpio(const char *filename, struct vector *v) {
close
(
fd
);
close
(
fd
);
}
}
static
void
cpio_vec_destroy
(
struct
vector
*
v
)
{
void
cpio_vec_destroy
(
struct
vector
*
v
)
{
// Free each cpio_entry
// Free each cpio_entry
cpio_entry
*
f
;
cpio_entry
*
f
;
vec_for_each
(
v
,
f
)
{
vec_for_each
(
v
,
f
)
{
...
@@ -140,7 +139,7 @@ static void cpio_vec_destroy(struct vector *v) {
...
@@ -140,7 +139,7 @@ static void cpio_vec_destroy(struct vector *v) {
vec_destroy
(
v
);
vec_destroy
(
v
);
}
}
static
void
cpio_rm
(
int
recursive
,
const
char
*
entry
,
struct
vector
*
v
)
{
void
cpio_rm
(
int
recursive
,
const
char
*
entry
,
struct
vector
*
v
)
{
cpio_entry
*
f
;
cpio_entry
*
f
;
vec_for_each
(
v
,
f
)
{
vec_for_each
(
v
,
f
)
{
if
(
strncmp
(
f
->
filename
,
entry
,
strlen
(
entry
))
==
0
)
{
if
(
strncmp
(
f
->
filename
,
entry
,
strlen
(
entry
))
==
0
)
{
...
@@ -156,7 +155,7 @@ static void cpio_rm(int recursive, const char *entry, struct vector *v) {
...
@@ -156,7 +155,7 @@ static void cpio_rm(int recursive, const char *entry, struct vector *v) {
}
}
}
}
static
void
cpio_mkdir
(
mode_t
mode
,
const
char
*
entry
,
struct
vector
*
v
)
{
void
cpio_mkdir
(
mode_t
mode
,
const
char
*
entry
,
struct
vector
*
v
)
{
cpio_entry
*
f
=
xcalloc
(
sizeof
(
*
f
),
1
);
cpio_entry
*
f
=
xcalloc
(
sizeof
(
*
f
),
1
);
f
->
mode
=
S_IFDIR
|
mode
;
f
->
mode
=
S_IFDIR
|
mode
;
f
->
namesize
=
strlen
(
entry
)
+
1
;
f
->
namesize
=
strlen
(
entry
)
+
1
;
...
@@ -165,7 +164,7 @@ static void cpio_mkdir(mode_t mode, const char *entry, struct vector *v) {
...
@@ -165,7 +164,7 @@ static void cpio_mkdir(mode_t mode, const char *entry, struct vector *v) {
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
entry
,
mode
);
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
entry
,
mode
);
}
}
static
void
cpio_add
(
mode_t
mode
,
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
)
{
void
cpio_add
(
mode_t
mode
,
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
)
{
int
fd
=
xopen
(
filename
,
O_RDONLY
);
int
fd
=
xopen
(
filename
,
O_RDONLY
);
cpio_entry
*
f
=
xcalloc
(
sizeof
(
*
f
),
1
);
cpio_entry
*
f
=
xcalloc
(
sizeof
(
*
f
),
1
);
f
->
mode
=
S_IFREG
|
mode
;
f
->
mode
=
S_IFREG
|
mode
;
...
@@ -180,7 +179,28 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, struc
...
@@ -180,7 +179,28 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, struc
fprintf
(
stderr
,
"Add entry [%s] (%04o)
\n
"
,
entry
,
mode
);
fprintf
(
stderr
,
"Add entry [%s] (%04o)
\n
"
,
entry
,
mode
);
}
}
static
void
cpio_test
(
struct
vector
*
v
)
{
void
cpio_mv
(
struct
vector
*
v
,
const
char
*
from
,
const
char
*
to
)
{
struct
cpio_entry
*
f
,
*
t
;
vec_for_each
(
v
,
f
)
{
if
(
strcmp
(
f
->
filename
,
from
)
==
0
)
{
fprintf
(
stderr
,
"Move [%s] -> [%s]
\n
"
,
from
,
to
);
vec_for_each
(
v
,
t
)
{
if
(
strcmp
(
t
->
filename
,
to
)
==
0
)
{
t
->
remove
=
1
;
break
;
}
}
free
(
f
->
filename
);
f
->
namesize
=
strlen
(
to
)
+
1
;
f
->
filename
=
strdup
(
to
);
return
;
}
}
fprintf
(
stderr
,
"Cannot find entry %s
\n
"
,
from
);
exit
(
1
);
}
void
cpio_test
(
struct
vector
*
v
)
{
#define STOCK_BOOT 0x0
#define STOCK_BOOT 0x0
#define MAGISK_PATCH 0x1
#define MAGISK_PATCH 0x1
#define OTHER_PATCH 0x2
#define OTHER_PATCH 0x2
...
@@ -205,72 +225,9 @@ static void cpio_test(struct vector *v) {
...
@@ -205,72 +225,9 @@ static void cpio_test(struct vector *v) {
exit
(
ret
);
exit
(
ret
);
}
}
int
check_verity_pattern
(
const
char
*
s
)
{
int
pos
=
0
;
if
(
s
[
0
]
==
','
)
++
pos
;
if
(
strncmp
(
s
+
pos
,
"verify"
,
6
)
==
0
)
pos
+=
6
;
else
if
(
strncmp
(
s
+
pos
,
"avb"
,
3
)
==
0
)
pos
+=
3
;
else
return
-
1
;
if
(
s
[
pos
]
==
'='
)
{
while
(
s
[
pos
]
!=
'\0'
&&
s
[
pos
]
!=
' '
&&
s
[
pos
]
!=
'\n'
&&
s
[
pos
]
!=
','
)
++
pos
;
}
return
pos
;
}
int
check_encryption_pattern
(
const
char
*
s
)
{
const
char
*
encrypt_list
[]
=
{
"forceencrypt"
,
"forcefdeorfbe"
,
NULL
};
for
(
int
i
=
0
;
encrypt_list
[
i
];
++
i
)
{
int
len
=
strlen
(
encrypt_list
[
i
]);
if
(
strncmp
(
s
,
encrypt_list
[
i
],
len
)
==
0
)
return
len
;
}
return
-
1
;
}
static
void
cpio_patch
(
struct
vector
*
v
,
int
keepverity
,
int
keepforceencrypt
)
{
void
cpio_extract
(
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
)
{
cpio_entry
*
f
;
int
skip
,
write
;
vec_for_each
(
v
,
f
)
{
if
(
!
keepverity
)
{
if
(
strstr
(
f
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
f
->
mode
))
{
write
=
0
;
for
(
int
read
=
0
;
read
<
f
->
filesize
;
++
write
,
++
read
)
{
if
((
skip
=
check_verity_pattern
(
f
->
data
+
read
))
>
0
)
{
fprintf
(
stderr
,
"Remove pattern [%.*s] in [%s]
\n
"
,
skip
,
f
->
data
+
read
,
f
->
filename
);
read
+=
skip
;
}
f
->
data
[
write
]
=
f
->
data
[
read
];
}
f
->
filesize
=
write
;
}
else
if
(
strcmp
(
f
->
filename
,
"verity_key"
)
==
0
)
{
fprintf
(
stderr
,
"Remove [verity_key]
\n
"
);
f
->
remove
=
1
;
}
}
if
(
!
keepforceencrypt
)
{
if
(
strstr
(
f
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
f
->
mode
))
{
write
=
0
;
for
(
int
read
=
0
;
read
<
f
->
filesize
;
++
write
,
++
read
)
{
if
((
skip
=
check_encryption_pattern
(
f
->
data
+
read
))
>
0
)
{
// assert(skip > 11)!
fprintf
(
stderr
,
"Replace pattern [%.*s] with [encryptable] in [%s]
\n
"
,
skip
,
f
->
data
+
read
,
f
->
filename
);
memcpy
(
f
->
data
+
write
,
"encryptable"
,
11
);
write
+=
11
;
read
+=
skip
;
}
f
->
data
[
write
]
=
f
->
data
[
read
];
}
f
->
filesize
=
write
;
}
}
}
}
static
void
cpio_extract
(
const
char
*
entry
,
const
char
*
filename
,
struct
vector
*
v
)
{
cpio_entry
*
f
;
cpio_entry
*
f
;
vec_for_each
(
v
,
f
)
{
vec_for_each
(
v
,
f
)
{
if
(
strcmp
(
f
->
filename
,
entry
)
==
0
&&
S_ISREG
(
f
->
mode
))
{
if
(
strcmp
(
f
->
filename
,
entry
)
==
0
&&
S_ISREG
(
f
->
mode
))
{
...
@@ -286,7 +243,7 @@ static void cpio_extract(const char *entry, const char *filename, struct vector
...
@@ -286,7 +243,7 @@ static void cpio_extract(const char *entry, const char *filename, struct vector
LOGE
(
"Cannot find the file entry [%s]
\n
"
,
entry
);
LOGE
(
"Cannot find the file entry [%s]
\n
"
,
entry
);
}
}
static
void
cpio_backup
(
const
char
*
orig
,
const
char
*
sha1
,
struct
vector
*
v
)
{
void
cpio_backup
(
const
char
*
orig
,
const
char
*
sha1
,
struct
vector
*
v
)
{
struct
vector
o_body
,
*
o
=
&
o_body
,
bak
;
struct
vector
o_body
,
*
o
=
&
o_body
,
bak
;
cpio_entry
*
m
,
*
n
,
*
rem
,
*
cksm
;
cpio_entry
*
m
,
*
n
,
*
rem
,
*
cksm
;
char
buf
[
PATH_MAX
];
char
buf
[
PATH_MAX
];
...
@@ -394,7 +351,7 @@ static void cpio_backup(const char *orig, const char *sha1, struct vector *v) {
...
@@ -394,7 +351,7 @@ static void cpio_backup(const char *orig, const char *sha1, struct vector *v) {
cpio_vec_destroy
(
o
);
cpio_vec_destroy
(
o
);
}
}
static
int
cpio_restore
(
struct
vector
*
v
)
{
int
cpio_restore
(
struct
vector
*
v
)
{
cpio_entry
*
f
,
*
n
;
cpio_entry
*
f
,
*
n
;
int
ret
=
1
;
int
ret
=
1
;
vec_for_each
(
v
,
f
)
{
vec_for_each
(
v
,
f
)
{
...
@@ -428,7 +385,7 @@ static int cpio_restore(struct vector *v) {
...
@@ -428,7 +385,7 @@ static int cpio_restore(struct vector *v) {
return
ret
;
return
ret
;
}
}
static
void
cpio_stocksha1
(
struct
vector
*
v
)
{
void
cpio_stocksha1
(
struct
vector
*
v
)
{
cpio_entry
*
f
;
cpio_entry
*
f
;
char
sha1
[
41
];
char
sha1
[
41
];
vec_for_each
(
v
,
f
)
{
vec_for_each
(
v
,
f
)
{
...
@@ -448,99 +405,3 @@ static void cpio_stocksha1(struct vector *v) {
...
@@ -448,99 +405,3 @@ static void cpio_stocksha1(struct vector *v) {
}
}
}
}
}
}
static
void
cpio_mv
(
struct
vector
*
v
,
const
char
*
from
,
const
char
*
to
)
{
struct
cpio_entry
*
f
,
*
t
;
vec_for_each
(
v
,
f
)
{
if
(
strcmp
(
f
->
filename
,
from
)
==
0
)
{
fprintf
(
stderr
,
"Move [%s] -> [%s]
\n
"
,
from
,
to
);
vec_for_each
(
v
,
t
)
{
if
(
strcmp
(
t
->
filename
,
to
)
==
0
)
{
t
->
remove
=
1
;
break
;
}
}
free
(
f
->
filename
);
f
->
namesize
=
strlen
(
to
)
+
1
;
f
->
filename
=
strdup
(
to
);
return
;
}
}
fprintf
(
stderr
,
"Cannot find entry %s
\n
"
,
from
);
exit
(
1
);
}
int
cpio_commands
(
const
char
*
command
,
int
argc
,
char
*
argv
[])
{
int
recursive
=
0
,
ret
=
0
;
command_t
cmd
;
char
*
incpio
=
argv
[
0
];
++
argv
;
--
argc
;
if
(
strcmp
(
command
,
"test"
)
==
0
)
{
cmd
=
TEST
;
}
else
if
(
strcmp
(
command
,
"restore"
)
==
0
)
{
cmd
=
RESTORE
;
}
else
if
(
strcmp
(
command
,
"stocksha1"
)
==
0
)
{
cmd
=
STOCKSHA1
;
}
else
if
(
argc
>=
1
&&
strcmp
(
command
,
"backup"
)
==
0
)
{
cmd
=
BACKUP
;
}
else
if
(
argc
>
0
&&
strcmp
(
command
,
"rm"
)
==
0
)
{
cmd
=
RM
;
if
(
argc
==
2
&&
strcmp
(
argv
[
0
],
"-r"
)
==
0
)
{
recursive
=
1
;
++
argv
;
--
argc
;
}
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"mv"
)
==
0
)
{
cmd
=
MV
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"patch"
)
==
0
)
{
cmd
=
PATCH
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"extract"
)
==
0
)
{
cmd
=
EXTRACT
;
}
else
if
(
argc
==
2
&&
strcmp
(
command
,
"mkdir"
)
==
0
)
{
cmd
=
MKDIR
;
}
else
if
(
argc
==
3
&&
strcmp
(
command
,
"add"
)
==
0
)
{
cmd
=
ADD
;
}
else
{
cmd
=
NONE
;
}
struct
vector
v
;
vec_init
(
&
v
);
parse_cpio
(
incpio
,
&
v
);
switch
(
cmd
)
{
case
TEST
:
cpio_test
(
&
v
);
break
;
case
RESTORE
:
ret
=
cpio_restore
(
&
v
);
break
;
case
STOCKSHA1
:
cpio_stocksha1
(
&
v
);
return
0
;
case
BACKUP
:
cpio_backup
(
argv
[
0
],
argc
>
1
?
argv
[
1
]
:
NULL
,
&
v
);
case
RM
:
cpio_rm
(
recursive
,
argv
[
0
],
&
v
);
break
;
case
PATCH
:
cpio_patch
(
&
v
,
strcmp
(
argv
[
0
],
"true"
)
==
0
,
strcmp
(
argv
[
1
],
"true"
)
==
0
);
break
;
case
EXTRACT
:
cpio_extract
(
argv
[
0
],
argv
[
1
],
&
v
);
break
;
case
MKDIR
:
cpio_mkdir
(
strtoul
(
argv
[
0
],
NULL
,
8
),
argv
[
1
],
&
v
);
break
;
case
ADD
:
cpio_add
(
strtoul
(
argv
[
0
],
NULL
,
8
),
argv
[
1
],
argv
[
2
],
&
v
);
break
;
case
MV
:
cpio_mv
(
&
v
,
argv
[
0
],
argv
[
1
]);
break
;
case
NONE
:
return
1
;
}
dump_cpio
(
incpio
,
&
v
);
cpio_vec_destroy
(
&
v
);
exit
(
ret
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment