aboutsummaryrefslogtreecommitdiff
path: root/src/lpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lpm.c')
-rw-r--r--src/lpm.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/lpm.c b/src/lpm.c
index 54eca32..2cfe1a6 100644
--- a/src/lpm.c
+++ b/src/lpm.c
@@ -553,6 +553,9 @@ static int gzip_read(mtar_t* tar, void* data, unsigned int size) { return gzread
static int gzip_seek(mtar_t* tar, unsigned int pos) { return gzseek(tar->stream, pos, SEEK_SET) >= 0 ? MTAR_ESUCCESS : -1; }
static int gzip_close(mtar_t* tar) { return gzclose(tar->stream) == Z_OK ? MTAR_ESUCCESS : -1; }
+#define FA_RDONLY 0x01 // FILE_ATTRIBUTE_READONLY
+#define FA_DIREC 0x10 // FILE_ATTRIBUTE_DIRECTORY
+
static int lpm_extract(lua_State* L) {
const char* src = luaL_checkstring(L, 1);
const char* dst = luaL_checkstring(L, 2);
@@ -578,7 +581,7 @@ static int lpm_extract(lua_State* L) {
}
char target[MAX_PATH];
int target_length = snprintf(target, sizeof(target), "%s/%s", dst, zip_name);
- if (!mkdirp(target, target_length)) {
+ if (mkdirp(target, target_length)) {
zip_fclose(zip_file);
zip_close(archive);
return luaL_error(L, "can't extract zip archive file %s, can't create directory %s: %s", src, target, strerror(errno));
@@ -590,6 +593,19 @@ static int lpm_extract(lua_State* L) {
zip_close(archive);
return luaL_error(L, "can't write file %s: %s", target, strerror(errno));
}
+ zip_uint8_t os;
+ zip_uint32_t attr;
+ zip_file_get_external_attributes(archive, i, 0, &os, &attr);
+ mode_t m = S_IRUSR | S_IRGRP | S_IROTH;
+ if (0 == (attr & FA_RDONLY))
+ m |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (attr & FA_DIREC)
+ m = (S_IFDIR | (m & ~S_IFMT)) | S_IXUSR | S_IXGRP | S_IXOTH;
+ if (chmod(target, m)) {
+ zip_fclose(zip_file);
+ zip_close(archive);
+ return luaL_error(L, "can't chmod file %s: %s", target, strerror(errno));
+ }
while (1) {
char buffer[8192];
zip_int64_t length = zip_fread(zip_file, buffer, sizeof(buffer));