mirror of
https://github.com/lxsang/antd-lua-plugin
synced 2025-07-26 10:49:51 +02:00
mimgrating from another repo
This commit is contained in:
50
lib/ulib/3rd/zip/main.c
Normal file
50
lib/ulib/3rd/zip/main.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zip.h"
|
||||
|
||||
// callback function
|
||||
int on_extract_entry(const char *filename, void *arg) {
|
||||
static int i = 0;
|
||||
int n = *(int *)arg;
|
||||
printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
/*
|
||||
Create a new zip archive with default compression level (6)
|
||||
*/
|
||||
/*
|
||||
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 0);
|
||||
// we should check if zip is NULL
|
||||
{
|
||||
zip_entry_open(zip, "foo-1.txt");
|
||||
{
|
||||
char *buf = "Some data here...";
|
||||
zip_entry_write(zip, buf, strlen(buf));
|
||||
}
|
||||
zip_entry_close(zip);
|
||||
|
||||
zip_entry_open(zip, "foo-2.txt");
|
||||
{
|
||||
// merge 3 files into one entry and compress them on-the-fly.
|
||||
zip_entry_fwrite(zip, "foo-2.1.txt");
|
||||
zip_entry_fwrite(zip, "foo-2.2.txt");
|
||||
zip_entry_fwrite(zip, "foo-2.3.txt");
|
||||
}
|
||||
zip_entry_close(zip);
|
||||
}
|
||||
// always remember to close and release resources
|
||||
zip_close(zip);
|
||||
*/
|
||||
|
||||
/*
|
||||
Extract a zip archive into /tmp folder
|
||||
*/
|
||||
int arg = 5;
|
||||
zip_extract(argv[1], "/Users/mrsang/Downloads/zip-master/src/tmp", on_extract_entry, &arg);
|
||||
|
||||
return 0;
|
||||
}
|
4916
lib/ulib/3rd/zip/miniz.c
Executable file
4916
lib/ulib/3rd/zip/miniz.c
Executable file
File diff suppressed because it is too large
Load Diff
471
lib/ulib/3rd/zip/zip.c
Executable file
471
lib/ulib/3rd/zip/zip.c
Executable file
@ -0,0 +1,471 @@
|
||||
/*
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "miniz.c"
|
||||
#include "zip.h"
|
||||
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
/* Win32, OS/2, DOS */
|
||||
#define HAS_DEVICE(P) ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && (P)[1] == ':')
|
||||
#define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
|
||||
#define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
#endif
|
||||
|
||||
#ifndef FILESYSTEM_PREFIX_LEN
|
||||
#define FILESYSTEM_PREFIX_LEN(P) 0
|
||||
#endif
|
||||
|
||||
#ifndef ISSLASH
|
||||
#define ISSLASH(C) ((C) == '/')
|
||||
#endif
|
||||
|
||||
#define cleanup(ptr) do { if (ptr) { free((void *)ptr); ptr = NULL; } } while (0)
|
||||
#define strclone(ptr) ((ptr) ? strdup(ptr) : NULL)
|
||||
|
||||
char *basename(const char *name) {
|
||||
char const *p;
|
||||
char const *base = name += FILESYSTEM_PREFIX_LEN (name);
|
||||
int all_slashes = 1;
|
||||
|
||||
for (p = name; *p; p++) {
|
||||
if (ISSLASH(*p))
|
||||
base = p + 1;
|
||||
else
|
||||
all_slashes = 0;
|
||||
}
|
||||
|
||||
/* If NAME is all slashes, arrange to return `/'. */
|
||||
if (*base == '\0' && ISSLASH(*name) && all_slashes)
|
||||
--base;
|
||||
|
||||
return (char *)base;
|
||||
}
|
||||
|
||||
static int mkpath(const char *path) {
|
||||
const int mode = 0755;
|
||||
char const *p;
|
||||
char npath[MAX_PATH + 1] = { 0 };
|
||||
int len = 0;
|
||||
|
||||
for (p = path; *p && len < MAX_PATH; p++) {
|
||||
if (ISSLASH(*p) && len > 0) {
|
||||
if (mkdir(npath, mode) == -1)
|
||||
if (errno != EEXIST) return -1;
|
||||
}
|
||||
npath[len++] = *p;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct zip_entry_t {
|
||||
const char *name;
|
||||
mz_uint64 uncomp_size;
|
||||
mz_uint64 comp_size;
|
||||
mz_uint32 uncomp_crc32;
|
||||
mz_uint64 offset;
|
||||
mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
|
||||
mz_uint64 header_offset;
|
||||
mz_uint16 method;
|
||||
mz_zip_writer_add_state state;
|
||||
tdefl_compressor comp;
|
||||
};
|
||||
|
||||
struct zip_t {
|
||||
mz_zip_archive archive;
|
||||
mz_uint level;
|
||||
struct zip_entry_t entry;
|
||||
};
|
||||
|
||||
struct zip_t *zip_open(const char *zipname, int level, int append) {
|
||||
struct zip_t *zip = NULL;
|
||||
struct MZ_FILE_STAT_STRUCT fstat;
|
||||
|
||||
if (!zipname || strlen(zipname) < 1) {
|
||||
// zip_t archive name is empty or NULL
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (level < 0) level = MZ_DEFAULT_LEVEL;
|
||||
if ((level & 0xF) > MZ_UBER_COMPRESSION) {
|
||||
// Wrong compression level
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
|
||||
if (zip) {
|
||||
zip->level = level;
|
||||
|
||||
if (append && MZ_FILE_STAT(zipname, &fstat) == 0) {
|
||||
// Append to an existing archive.
|
||||
if (!mz_zip_reader_init_file(&(zip->archive), zipname, level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
|
||||
cleanup(zip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_init_from_reader(&(zip->archive), zipname)) {
|
||||
mz_zip_reader_end(&(zip->archive));
|
||||
cleanup(zip);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// Create a new archive.
|
||||
if (!mz_zip_writer_init_file(&(zip->archive), zipname, 0)) {
|
||||
// Cannot initialize zip_archive writer
|
||||
cleanup(zip);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return zip;
|
||||
}
|
||||
|
||||
void zip_close(struct zip_t *zip) {
|
||||
if (zip) {
|
||||
// Always finalize, even if adding failed for some reason, so we have a valid central directory.
|
||||
mz_zip_writer_finalize_archive(&(zip->archive));
|
||||
mz_zip_writer_end(&(zip->archive));
|
||||
|
||||
cleanup(zip);
|
||||
}
|
||||
}
|
||||
|
||||
int zip_entry_open(struct zip_t *zip, const char *entryname) {
|
||||
size_t entrylen = 0;
|
||||
mz_zip_archive *pzip = NULL;
|
||||
mz_uint num_alignment_padding_bytes, level;
|
||||
|
||||
if (!zip || !entryname) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
entrylen = strlen(entryname);
|
||||
if (entrylen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip->entry.name = strclone(entryname);
|
||||
if (!zip->entry.name) {
|
||||
// Cannot parse zip entry name
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip->entry.comp_size = 0;
|
||||
zip->entry.uncomp_size = 0;
|
||||
zip->entry.uncomp_crc32 = MZ_CRC32_INIT;
|
||||
zip->entry.offset = zip->archive.m_archive_size;
|
||||
zip->entry.header_offset = zip->archive.m_archive_size;
|
||||
memset(zip->entry.header, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE * sizeof(mz_uint8));
|
||||
zip->entry.method = 0;
|
||||
|
||||
pzip = &(zip->archive);
|
||||
num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pzip);
|
||||
|
||||
if (!pzip->m_pState || (pzip->m_zip_mode != MZ_ZIP_MODE_WRITING)) {
|
||||
// Wrong zip mode
|
||||
return -1;
|
||||
}
|
||||
if (zip->level & MZ_ZIP_FLAG_COMPRESSED_DATA) {
|
||||
// Wrong zip compression level
|
||||
return -1;
|
||||
}
|
||||
// no zip64 support yet
|
||||
if ((pzip->m_total_files == 0xFFFF) || ((pzip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + entrylen) > 0xFFFFFFFF)) {
|
||||
// No zip64 support yet
|
||||
return -1;
|
||||
}
|
||||
if (!mz_zip_writer_write_zeros(pzip, zip->entry.offset, num_alignment_padding_bytes + sizeof(zip->entry.header))) {
|
||||
// Cannot memset zip entry header
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip->entry.header_offset += num_alignment_padding_bytes;
|
||||
if (pzip->m_file_offset_alignment) { MZ_ASSERT((zip->entry.header_offset & (pzip->m_file_offset_alignment - 1)) == 0); }
|
||||
zip->entry.offset += num_alignment_padding_bytes + sizeof(zip->entry.header);
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, zip->entry.name, entrylen) != entrylen) {
|
||||
// Cannot write data to zip entry
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip->entry.offset += entrylen;
|
||||
level = zip->level & 0xF;
|
||||
if (level) {
|
||||
zip->entry.state.m_pZip = pzip;
|
||||
zip->entry.state.m_cur_archive_file_ofs = zip->entry.offset;
|
||||
zip->entry.state.m_comp_size = 0;
|
||||
|
||||
if (tdefl_init(&(zip->entry.comp), mz_zip_writer_add_put_buf_callback, &(zip->entry.state), tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) {
|
||||
// Cannot initialize the zip compressor
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zip_entry_close(struct zip_t *zip) {
|
||||
mz_zip_archive *pzip = NULL;
|
||||
mz_uint level;
|
||||
tdefl_status done;
|
||||
mz_uint16 entrylen;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
mz_uint16 dos_time, dos_date;
|
||||
|
||||
if (!zip) {
|
||||
// zip_t handler is not initialized
|
||||
return -1;
|
||||
}
|
||||
|
||||
pzip = &(zip->archive);
|
||||
level = zip->level & 0xF;
|
||||
if (level) {
|
||||
done = tdefl_compress_buffer(&(zip->entry.comp), "", 0, TDEFL_FINISH);
|
||||
if (done != TDEFL_STATUS_DONE && done != TDEFL_STATUS_OKAY) {
|
||||
// Cannot flush compressed buffer
|
||||
cleanup(zip->entry.name);
|
||||
return -1;
|
||||
}
|
||||
zip->entry.comp_size = zip->entry.state.m_comp_size;
|
||||
zip->entry.offset = zip->entry.state.m_cur_archive_file_ofs;
|
||||
zip->entry.method = MZ_DEFLATED;
|
||||
}
|
||||
|
||||
entrylen = (mz_uint16)strlen(zip->entry.name);
|
||||
t = time(NULL);
|
||||
tm = localtime(&t);
|
||||
dos_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
|
||||
dos_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
|
||||
|
||||
// no zip64 support yet
|
||||
if ((zip->entry.comp_size > 0xFFFFFFFF) || (zip->entry.offset > 0xFFFFFFFF)) {
|
||||
// No zip64 support, yet
|
||||
cleanup(zip->entry.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_create_local_dir_header(pzip, zip->entry.header, entrylen, 0, zip->entry.uncomp_size, zip->entry.comp_size, zip->entry.uncomp_crc32, zip->entry.method, 0, dos_time, dos_date)) {
|
||||
// Cannot create zip entry header
|
||||
cleanup(zip->entry.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.header_offset, zip->entry.header, sizeof(zip->entry.header)) != sizeof(zip->entry.header)) {
|
||||
// Cannot write zip entry header
|
||||
cleanup(zip->entry.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_add_to_central_dir(pzip, zip->entry.name, entrylen, NULL, 0, "", 0, zip->entry.uncomp_size, zip->entry.comp_size, zip->entry.uncomp_crc32, zip->entry.method, 0, dos_time, dos_date, zip->entry.header_offset, 0)) {
|
||||
// Cannot write to zip central dir
|
||||
cleanup(zip->entry.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pzip->m_total_files++;
|
||||
pzip->m_archive_size = zip->entry.offset;
|
||||
|
||||
cleanup(zip->entry.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
|
||||
mz_uint level;
|
||||
mz_zip_archive *pzip = NULL;
|
||||
tdefl_status status;
|
||||
|
||||
if (!zip) {
|
||||
// zip_t handler is not initialized
|
||||
return -1;
|
||||
}
|
||||
|
||||
pzip = &(zip->archive);
|
||||
if (buf && bufsize > 0) {
|
||||
zip->entry.uncomp_size += bufsize;
|
||||
zip->entry.uncomp_crc32 = (mz_uint32)mz_crc32(zip->entry.uncomp_crc32, (const mz_uint8 *)buf, bufsize);
|
||||
|
||||
level = zip->level & 0xF;
|
||||
if (!level) {
|
||||
if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf, bufsize) != bufsize)) {
|
||||
// Cannot write buffer
|
||||
return -1;
|
||||
}
|
||||
zip->entry.offset += bufsize;
|
||||
zip->entry.comp_size += bufsize;
|
||||
} else {
|
||||
status = tdefl_compress_buffer(&(zip->entry.comp), buf, bufsize, TDEFL_NO_FLUSH);
|
||||
if (status != TDEFL_STATUS_DONE && status != TDEFL_STATUS_OKAY) {
|
||||
// Cannot compress buffer
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zip_entry_fwrite(struct zip_t *zip, const char *filename) {
|
||||
int status = 0;
|
||||
size_t n = 0;
|
||||
FILE *stream = NULL;
|
||||
mz_uint8 buf[MZ_ZIP_MAX_IO_BUF_SIZE] = { 0 };
|
||||
|
||||
if (!zip) {
|
||||
// zip_t handler is not initialized
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream = fopen(filename, "rb");
|
||||
if (!stream) {
|
||||
// Cannot open filename
|
||||
return -1;
|
||||
}
|
||||
|
||||
while((n = fread(buf, sizeof(mz_uint8), MZ_ZIP_MAX_IO_BUF_SIZE, stream)) > 0) {
|
||||
if (zip_entry_write(zip, buf, n) < 0) {
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int zip_create(const char *zipname, const char *filenames[], size_t len) {
|
||||
int status = 0;
|
||||
size_t i;
|
||||
mz_zip_archive zip_archive;
|
||||
|
||||
if (!zipname || strlen(zipname) < 1) {
|
||||
// zip_t archive name is empty or NULL
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a new archive.
|
||||
if (!memset(&(zip_archive), 0, sizeof(zip_archive))) {
|
||||
// Cannot memset zip archive
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_init_file(&zip_archive, zipname, 0)) {
|
||||
// Cannot initialize zip_archive writer
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
const char *name = filenames[i];
|
||||
if (!name) {
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_add_file(&zip_archive, basename(name), name, "", 0, ZIP_DEFAULT_COMPRESSION_LEVEL)) {
|
||||
// Cannot add file to zip_archive
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mz_zip_writer_finalize_archive(&zip_archive);
|
||||
mz_zip_writer_end(&zip_archive);
|
||||
return status;
|
||||
}
|
||||
|
||||
int zip_extract(const char *zipname, const char *dir, int (* on_extract)(const char *filename, void *arg), void *arg) {
|
||||
int status = 0;
|
||||
mz_uint i, n;
|
||||
char path[MAX_PATH + 1] = { 0 };
|
||||
mz_zip_archive zip_archive;
|
||||
mz_zip_archive_file_stat info;
|
||||
size_t dirlen = 0;
|
||||
|
||||
if (!memset(&(zip_archive), 0, sizeof(zip_archive))) {
|
||||
// Cannot memset zip archive
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!zipname || !dir) {
|
||||
// Cannot parse zip archive name
|
||||
return -1;
|
||||
}
|
||||
|
||||
dirlen = strlen(dir);
|
||||
if (dirlen + 1 > MAX_PATH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now try to open the archive.
|
||||
if (!mz_zip_reader_init_file(&zip_archive, zipname, 0)) {
|
||||
// Cannot initialize zip_archive reader
|
||||
status = -1;
|
||||
goto finally;
|
||||
}
|
||||
|
||||
strcpy(path, dir);
|
||||
if (!ISSLASH(path[dirlen -1])) {
|
||||
#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
|
||||
path[dirlen] = '\\';
|
||||
#else
|
||||
path[dirlen] = '/';
|
||||
#endif
|
||||
++dirlen;
|
||||
}
|
||||
|
||||
// Get and print information about each file in the archive.
|
||||
n = mz_zip_reader_get_num_files(&zip_archive);
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &info)) {
|
||||
// Cannot get information about zip archive;
|
||||
//printf("Cant get information about fimes");
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(&path[dirlen], info.m_filename, MAX_PATH - dirlen);
|
||||
if (mkpath(path) < 0) {
|
||||
// Cannot make a path
|
||||
//printf("Cant create path\n");
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
// verify if the path is directory first
|
||||
// issue fixed by xsang.le@gmail.com
|
||||
struct stat path_stat;
|
||||
if(stat(path, &path_stat) != 0 || !(path_stat.st_mode & S_IFDIR))
|
||||
if (!mz_zip_reader_extract_to_file(&zip_archive, i, path, 0)) {
|
||||
// Cannot extract zip archive to file
|
||||
//printf("Cant extract %s\n", path);
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (on_extract) {
|
||||
if (on_extract(path, arg) < 0) {
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close the archive, freeing any resources it was using
|
||||
if (!mz_zip_reader_end(&zip_archive)) {
|
||||
// Cannot end zip reader
|
||||
status = -1;
|
||||
}
|
||||
|
||||
finally:
|
||||
return status;
|
||||
}
|
90
lib/ulib/3rd/zip/zip.h
Executable file
90
lib/ulib/3rd/zip/zip.h
Executable file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef ZIP_H
|
||||
#define ZIP_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 32767 /* # chars in a path name including NULL */
|
||||
#endif
|
||||
|
||||
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
||||
|
||||
/* This data structure is used throughout the library to represent zip archive - forward declaration. */
|
||||
struct zip_t;
|
||||
|
||||
/*
|
||||
Opens zip archive with compression level.
|
||||
If append is 0 then new archive will be created, otherwise function will try to append to the specified zip archive,
|
||||
instead of creating a new one.
|
||||
Compression levels: 0-9 are the standard zlib-style levels.
|
||||
Returns pointer to zip_t structure or NULL on error.
|
||||
*/
|
||||
struct zip_t *zip_open(const char *zipname, int level, int append);
|
||||
|
||||
/* Closes zip archive, releases resources - always finalize. */
|
||||
void zip_close(struct zip_t *zip);
|
||||
|
||||
/*
|
||||
Opens a new entry for writing in a zip archive.
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_entry_open(struct zip_t *zip, const char *entryname);
|
||||
|
||||
/*
|
||||
Closes zip entry, flushes buffer and releases resources.
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_entry_close(struct zip_t *zip);
|
||||
|
||||
/*
|
||||
Compresses an input buffer for the current zip entry.
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
|
||||
|
||||
/*
|
||||
Compresses a file for the current zip entry.
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_entry_fwrite(struct zip_t *zip, const char *filename);
|
||||
|
||||
/*
|
||||
Creates a new archive and puts len files into a single zip archive
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_create(const char *zipname, const char *filenames[], size_t len);
|
||||
|
||||
/*
|
||||
Extracts a zip archive file into dir.
|
||||
If on_extract_entry is not NULL, the callback will be called after successfully extracted each zip entry.
|
||||
Returning a negative value from the callback will cause abort the extract and return an error.
|
||||
|
||||
The last argument (void *arg) is optional, which you can use to pass some data to the on_extract_entry callback.
|
||||
|
||||
Returns negative number (< 0) on error, 0 on success.
|
||||
*/
|
||||
int zip_extract(const char *zipname, const char *dir, int (* on_extract_entry)(const char *filename, void *arg), void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
7
lib/ulib/Makefile
Normal file
7
lib/ulib/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
include ../../../../var.mk
|
||||
|
||||
LIB_NAME=ulib.$(LIB_EXT)
|
||||
LIB_OBJ= ulib.o 3rd/zip/zip.o
|
||||
|
||||
|
||||
include ../../lib.mk
|
631
lib/ulib/ulib.c
Normal file
631
lib/ulib/ulib.c
Normal file
@ -0,0 +1,631 @@
|
||||
#ifdef LINUX
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include "../lualib.h"
|
||||
#include "utils.h"
|
||||
// zip library
|
||||
#include "3rd/zip/zip.h"
|
||||
|
||||
static int l_check_login (lua_State *L) {
|
||||
#ifdef LINUX
|
||||
const char* username = luaL_checkstring(L,1);
|
||||
const char* password = luaL_checkstring(L,2);
|
||||
|
||||
char *encrypted;
|
||||
struct passwd *pwd;
|
||||
struct spwd *spwd;
|
||||
/* Look up password and shadow password records for username */
|
||||
pwd = getpwnam(username);
|
||||
if (pwd == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Cannot find pwd record of %s\n", username );
|
||||
return 1;
|
||||
}
|
||||
spwd = getspnam(username);
|
||||
if (spwd == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("no permission to read shadow password file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (spwd != NULL) /* If there is a shadow password record */
|
||||
{
|
||||
pwd->pw_passwd = spwd->sp_pwdp; /* Use the shadow password */
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("shadow record is null \n" );
|
||||
return 1;
|
||||
}
|
||||
/* Encrypt password and erase cleartext version immediately */
|
||||
encrypted = crypt(password, pwd->pw_passwd);
|
||||
if (encrypted == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Cant crypt \n" );
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(encrypted, pwd->pw_passwd) == 0)
|
||||
{
|
||||
lua_pushboolean(L,1);
|
||||
printf("%s\n","Successful login" );
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Password incorrect \n" );
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
// macos
|
||||
// just pass the check, for test only
|
||||
lua_pushboolean(L,1);
|
||||
printf("%s\n","Successful login" );
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
static void get_userId(const char* name, uid_t* uid,gid_t* gid )
|
||||
{
|
||||
struct passwd *pwd;
|
||||
uid_t u;
|
||||
char *endptr;
|
||||
if (name == NULL || *name == '\0')
|
||||
{
|
||||
*uid = -1; *gid=-1;
|
||||
return;
|
||||
}
|
||||
u = strtol(name, &endptr, 10);
|
||||
if (*endptr == '\0')
|
||||
{
|
||||
*uid = u;
|
||||
*gid = -1;
|
||||
return;
|
||||
}
|
||||
pwd = getpwnam(name);
|
||||
if (pwd == NULL)
|
||||
{
|
||||
*uid = -1; *gid=-1;
|
||||
return;
|
||||
}
|
||||
*uid = pwd->pw_uid;
|
||||
*gid = pwd->pw_gid;
|
||||
}
|
||||
static int l_fork(lua_State* L)
|
||||
{
|
||||
int pid = fork();
|
||||
lua_pushnumber(L, pid);
|
||||
return 1;
|
||||
}
|
||||
static int l_waitpid(lua_State* L)
|
||||
{
|
||||
int pid = luaL_checknumber(L,1);
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
lua_pushnumber(L, status);
|
||||
}
|
||||
static int l_setuid(lua_State* L)
|
||||
{
|
||||
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
||||
if((int)uid != -1)
|
||||
{
|
||||
if(seteuid(uid) < 0)
|
||||
{
|
||||
printf("UID set problem: %s\n", strerror(errno));
|
||||
lua_pushboolean(L,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("UID set\n");
|
||||
lua_pushboolean(L,1);
|
||||
}
|
||||
}
|
||||
else
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
static int l_setgid(lua_State* L)
|
||||
{
|
||||
uid_t gid = (uid_t) luaL_checknumber(L,1);
|
||||
if((int)gid != -1)
|
||||
{
|
||||
if(setegid(gid) < 0)
|
||||
{
|
||||
printf("GID set problem: %s\n", strerror(errno));
|
||||
lua_pushboolean(L,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("GID set\n");
|
||||
lua_pushboolean(L,1);
|
||||
}
|
||||
}
|
||||
else
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
static int l_getuid(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L,1);
|
||||
uid_t uid = -1;
|
||||
uid_t gid = -1;
|
||||
get_userId(name,&uid,&gid);
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L,"id");
|
||||
lua_pushnumber(L,uid);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"gid");
|
||||
lua_pushnumber(L,gid);
|
||||
lua_settable(L,-3);
|
||||
|
||||
int j, ngroups = 30; //only first 10 group
|
||||
gid_t *groups;
|
||||
struct group *gr;
|
||||
// find all the groups
|
||||
if((int)uid != -1 && (int)gid != -1)
|
||||
{
|
||||
/* Retrieve group list */
|
||||
groups = malloc(ngroups * sizeof (gid_t));
|
||||
if (groups == NULL) {
|
||||
LOG("malloc eror \n");
|
||||
return 1;
|
||||
}
|
||||
if (getgrouplist(name, gid, groups, &ngroups) == -1) {
|
||||
free(groups);
|
||||
LOG("getgrouplist() returned -1; ngroups = %d\n", ngroups);
|
||||
return 1;
|
||||
}
|
||||
/* retrieved groups, along with group names */
|
||||
lua_pushstring(L,"groups");
|
||||
lua_newtable(L);
|
||||
|
||||
for (j = 0; j < ngroups; j++) {
|
||||
gr = getgrgid(groups[j]);
|
||||
if (gr != NULL)
|
||||
{
|
||||
//printf("%d: (%s)\n", groups[j],gr->gr_name);
|
||||
lua_pushnumber(L, groups[j]);
|
||||
lua_pushstring(L, gr->gr_name);
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
free(groups);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int l_file_stat(lua_State* L, const char* path)
|
||||
{
|
||||
//const char* path = luaL_checkstring(L,-1);
|
||||
//printf("PATH %s\n", path);
|
||||
//lua_pop(L,1);
|
||||
char date[64];
|
||||
struct stat st;
|
||||
if( stat(path, &st) == 0 )
|
||||
{
|
||||
// recore for file
|
||||
lua_newtable(L);
|
||||
|
||||
//type
|
||||
lua_pushstring(L,"type");
|
||||
if(S_ISDIR(st.st_mode))
|
||||
lua_pushstring(L,"dir");
|
||||
else
|
||||
lua_pushstring(L,"file");
|
||||
lua_settable(L,-3);
|
||||
|
||||
//ctime
|
||||
lua_pushstring(L,"ctime");
|
||||
strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&(st.st_ctime)));
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
//mtime
|
||||
|
||||
lua_pushstring(L,"mtime");
|
||||
strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&(st.st_mtime)));
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
|
||||
//size
|
||||
lua_pushstring(L,"size");
|
||||
lua_pushnumber(L,st.st_size);
|
||||
lua_settable(L,-3);
|
||||
//mime
|
||||
if(S_ISDIR(st.st_mode))
|
||||
{
|
||||
lua_pushstring(L,"mime");
|
||||
lua_pushstring(L, "dir");
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L,"mime");
|
||||
lua_pushstring(L, mime(path));
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
|
||||
// uid
|
||||
lua_pushstring(L,"uid");
|
||||
lua_pushnumber(L,st.st_uid);
|
||||
lua_settable(L,-3);
|
||||
// gid
|
||||
lua_pushstring(L,"gid");
|
||||
lua_pushnumber(L,st.st_gid);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"permissions");
|
||||
sprintf(date," (%3o)", st.st_mode&0777);
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
|
||||
// permission
|
||||
lua_pushstring(L,"perm");
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L,"owner");
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"read");
|
||||
lua_pushboolean(L, (st.st_mode & S_IRUSR)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"write");
|
||||
lua_pushboolean(L, (st.st_mode & S_IWUSR)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"exec");
|
||||
lua_pushboolean(L, (st.st_mode & S_IXUSR)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
//end owner
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"group");
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"read");
|
||||
lua_pushboolean(L, (st.st_mode & S_IRGRP)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"write");
|
||||
lua_pushboolean(L, (st.st_mode & S_IWGRP)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"exec");
|
||||
lua_pushboolean(L, (st.st_mode & S_IXGRP)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
//end owner
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"other");
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"read");
|
||||
lua_pushboolean(L, (st.st_mode & S_IROTH)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"write");
|
||||
lua_pushboolean(L, (st.st_mode & S_IWOTH)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
lua_pushstring(L,"exec");
|
||||
lua_pushboolean(L, (st.st_mode & S_IXOTH)==0?0:1);
|
||||
lua_settable(L,-3);
|
||||
//end owner
|
||||
lua_settable(L,-3);
|
||||
|
||||
// end permission
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_newtable(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_file_info(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
l_file_stat(L,path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_file_move(lua_State* L)
|
||||
{
|
||||
const char* old = luaL_checkstring(L,1);
|
||||
const char* new = luaL_checkstring(L,2);
|
||||
//printf("MOVE %s to %s\n",old,new);
|
||||
lua_pushboolean(L, rename(old,new)==0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_read_dir(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
const char* prefix = luaL_checkstring(L,2);
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
d = opendir(path);
|
||||
char buff[1024];
|
||||
lua_newtable(L);
|
||||
if (d)
|
||||
{
|
||||
int id=0;
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
//ignore curent directory, parent directory
|
||||
if(strcmp(dir->d_name,".") == 0 ||
|
||||
strcmp(dir->d_name,"..")==0/*|| *(dir->d_name)=='.'*/) continue;
|
||||
sprintf(buff,"%s/%s",path,dir->d_name);
|
||||
lua_pushnumber(L,id);
|
||||
//lua_pushstring(L,buff);
|
||||
l_file_stat(L,buff);
|
||||
|
||||
lua_pushstring(L,"filename");
|
||||
lua_pushstring(L,dir->d_name);
|
||||
lua_settable(L,-3);
|
||||
|
||||
sprintf(buff,"%s/%s",prefix,dir->d_name);
|
||||
//printf("FILE %s\n",buff );
|
||||
lua_pushstring(L,"path");
|
||||
lua_pushstring(L,buff);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_settable(L,-3);
|
||||
|
||||
id++;
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L,"error");
|
||||
lua_pushstring(L,"Resource not found");
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_chown(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
int id = luaL_checknumber(L,2);
|
||||
int gid = luaL_checknumber(L,3);
|
||||
lua_pushboolean(L, chown(path,id,gid) == 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_mkdir(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
lua_pushboolean(L, mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0);
|
||||
return 1;
|
||||
}
|
||||
static int l_exist(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
lua_pushboolean(L,access( path, F_OK ) != -1 );
|
||||
return 1;
|
||||
}
|
||||
static int _recursive_delete(const char* path)
|
||||
{
|
||||
if(is_dir(path) == 1)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
d = opendir(path);
|
||||
char buff[1024];
|
||||
if (d)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
//ignore current & parent dir
|
||||
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
||||
// get the file
|
||||
sprintf(buff,"%s/%s",path,dir->d_name);
|
||||
if(_recursive_delete(buff) == -1) return -1;
|
||||
}
|
||||
closedir(d);
|
||||
// remove dir
|
||||
if(rmdir(path) != 0) return -1;
|
||||
} else return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// file remove
|
||||
if(remove(path) != 0) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int l_delete(lua_State* L)
|
||||
{
|
||||
const char* f = luaL_checkstring(L,1);
|
||||
lua_pushboolean(L,_recursive_delete(f) == 0);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Only use this for simple command
|
||||
* Be careful to expose this function
|
||||
* to user. This can cause a serious
|
||||
* security problem
|
||||
*/
|
||||
static int l_cmd_open(lua_State* L)
|
||||
{
|
||||
FILE *fp;
|
||||
const char* cmd = luaL_checkstring(L,1);
|
||||
|
||||
/* Open the command for reading. */
|
||||
fp = popen(cmd, "r");
|
||||
if (fp == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
/*return the fd to lua
|
||||
* user can use this to
|
||||
read the output data*/
|
||||
intptr_t pt = (intptr_t)fp;
|
||||
lua_pushnumber(L, pt);
|
||||
return 1;
|
||||
}
|
||||
static int l_cmd_read(lua_State* L)
|
||||
{
|
||||
/* Read the output a line at a time - output it.
|
||||
read user defined data of std
|
||||
*/
|
||||
FILE * fd;
|
||||
intptr_t pt = (intptr_t)luaL_checknumber(L, 1);
|
||||
fd = (FILE*)pt;
|
||||
if(fd == NULL)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
char buff[1024];
|
||||
if(fgets(buff, sizeof(buff)-1, fd) != NULL) {
|
||||
lua_pushstring(L,buff);
|
||||
} else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
/* close */
|
||||
//pclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int l_cmd_close(lua_State* L)
|
||||
{
|
||||
/* Read the output a line at a time - output it.
|
||||
read user defined data of std
|
||||
*/
|
||||
FILE * fd;
|
||||
intptr_t pt = (intptr_t)luaL_checknumber(L, 1);
|
||||
fd = (FILE*)pt;
|
||||
if(fd == NULL)
|
||||
{
|
||||
pclose(fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*zip file handler
|
||||
* using miniz to compress and uncompress zip file
|
||||
*/
|
||||
|
||||
static int l_unzip(lua_State* L)
|
||||
{
|
||||
const char* src = luaL_checkstring(L,1);
|
||||
const char* dest = luaL_checkstring(L,2);
|
||||
|
||||
if(zip_extract(src, dest, NULL, NULL) == -1)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_to_zip(struct zip_t * zip, const char* path, const char* root)
|
||||
{
|
||||
int st = is_dir(path);
|
||||
if(st == -1) return -1;
|
||||
if(st)
|
||||
{
|
||||
// read directory
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
//struct stat st;
|
||||
d = opendir(path);
|
||||
if (d)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
//ignore curent directory, parent directory
|
||||
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
||||
// add file to zip
|
||||
char* p1 = __s("%s/%s", path, dir->d_name);
|
||||
char* p2 = __s("%s/%s",root,dir->d_name);
|
||||
if(_add_to_zip(zip,p1,p2) == -1)
|
||||
{
|
||||
free(p1);
|
||||
free(p2);
|
||||
return -1;
|
||||
}
|
||||
free(p1);
|
||||
free(p2);
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it is a file
|
||||
// add it to zip
|
||||
if(zip_entry_open(zip, root) == -1) return -1;
|
||||
if(zip_entry_fwrite(zip, path) == -1) return -1;
|
||||
zip_entry_close(zip);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_zip(lua_State* L)
|
||||
{
|
||||
const char* src = luaL_checkstring(L,1);
|
||||
const char* dest = luaL_checkstring(L,2);
|
||||
|
||||
// create a zip handler
|
||||
struct zip_t *zip = zip_open(dest, ZIP_DEFAULT_COMPRESSION_LEVEL, 0);
|
||||
|
||||
if(zip == NULL) goto pfalse;
|
||||
|
||||
if(_add_to_zip(zip,src,"") == -1) goto pfalse;
|
||||
|
||||
zip_close(zip);
|
||||
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
|
||||
// return false
|
||||
pfalse:
|
||||
// TODO remove if filed is created
|
||||
if(zip) zip_close(zip);
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg _lib [] = {
|
||||
{"auth", l_check_login},
|
||||
{"read_dir",l_read_dir},
|
||||
{"file_stat",l_file_info},
|
||||
{"uid",l_getuid},
|
||||
{"setuid", l_setuid},
|
||||
{"setgid", l_setgid},
|
||||
{"fork", l_fork},
|
||||
{"waitpid", l_waitpid},
|
||||
{"chown",l_chown},
|
||||
{"delete", l_delete},
|
||||
{"exists",l_exist},
|
||||
{"mkdir",l_mkdir},
|
||||
{"cmdopen",l_cmd_open},
|
||||
{"cmdread",l_cmd_read},
|
||||
{"cmdclose",l_cmd_close},
|
||||
{"move",l_file_move},
|
||||
{"unzip",l_unzip},
|
||||
{"zip",l_zip},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
int luaopen_ulib(lua_State *L)
|
||||
{
|
||||
luaL_newlib(L, _lib);
|
||||
return 1;
|
||||
}
|
Reference in New Issue
Block a user