Git Product home page Git Product logo

zipwriter's Introduction

Library for creating ZIP archive for Lua 5.1/5.2/5.3

Based on http://wiki.tcl.tk/15158

Build Status Coverage Status Licence

Documentation

Documentation

Dependencies

Core

Optional

Test

Supports

  • write to non seekable stream
  • utf8 file names in archives (required iconv)
  • ZIP64 (does not use stream:seek())

Install

Since version 0.1.5 rockspec does not have any dependencies because there no way to specify them as optional. E.g. if you already have installed lua-zlib and you then install lzlib then your existed code may stop working. So you have to install appropriate library by hand. Also some dependencies need only for specific Lua version.

  • Install zlib binding
luarocks install lua-zlib

or

luarocks install lzlib
  • Lua 5.1/5.2/JIT dependencies
luarocks install struct
  • Lua 5.1 dependencies
luarocks install bit32
  • Install ZipWriter itself
luarocks install zipwriter

Usage

Make simple archive

local ZipWriter = require "ZipWriter"

function make_reader(fname)
  local f = assert(io.open(fname, 'rb'))
  local chunk_size = 1024
  local desc = { -- `-rw-r-----` on Unix
    istext   = true,
    isfile   = true,
    isdir    = false,
    mtime    = 1348048902, -- lfs.attributes('modification')
    platform = 'unix',
    exattrib = {
      ZipWriter.NIX_FILE_ATTR.IFREG,
      ZipWriter.NIX_FILE_ATTR.IRUSR,
      ZipWriter.NIX_FILE_ATTR.IWUSR,
      ZipWriter.NIX_FILE_ATTR.IRGRP,
      ZipWriter.DOS_FILE_ATTR.ARCH,
    },
  }
  return desc, desc.isfile and function()
    local chunk = f:read(chunk_size)
    if chunk then return chunk end
    f:close()
  end
end

ZipStream = ZipWriter.new()
ZipStream:open_stream( assert(io.open('readme.zip', 'w+b')), true )
ZipStream:write('README.md', make_reader('README.md'))
ZipStream:close()

Reading file from FTP and saving archive on FTP

local ZipWriter = require "ZipWriter"
local FTP = require "socket.ftp"

local ZipStream = ZipWriter.new()

-- write zip file directly to ftp
-- lua 5.1 needs coco
ZipStream:open_writer(ZipWriter.co_writer(function(reader)
  FTP.put{
    -- ftp params ...
    path = 'test.zip';
    src  = reader;
  }
end))

-- read from FTP
FTP.get{
  -- ftp params ...
  path = 'test.txt'
  sink = ZipWriter.sink(ZipStream, 'test.txt', {isfile=true;istext=1})
}

ZipStream:close()

Make encrypted archive

local ZipWriter  = require"ZipWriter"
local AesEncrypt = require"ZipWriter.encrypt.aes"

ZipStream = ZipWriter.new{
  encrypt = AesEncrypt.new('password')
}

-- as before

zipwriter's People

Contributors

bitdeli-chef avatar moteus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

zipwriter's Issues

Create more convinient way to set extattr value.

See #2.

This is what I do.

-- Based on
-- http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute

-- 1000|000|110100000|00000000|00100000
-- TTTT|sst|rwxrwxrwx|00000000|00ADVSHR
-- ^^^^|___|_________|________|________ file type as explained above
--     |^^^|_________|________|________ setuid, setgid, sticky
--     |   |^^^^^^^^^|________|________ permissions
--     |   |         |^^^^^^^^|________ This is the "lower-middle byte" your post mentions
--     |   |         |        |^^^^^^^^ DOS attribute bits

local function o(n) return tonumber(n, 8) end

local NIX_FILE_ATTR = {
  IFIFO  = o"010000";  -- /* named pipe (fifo) */
  IFCHR  = o"020000";  -- /* character special */
  IFDIR  = o"040000";  -- /* directory */
  IFBLK  = o"060000";  -- /* block special */
  IFREG  = o"100000";  -- /* regular */
  IFLNK  = o"120000";  -- /* symbolic link */
  IFSOCK = o"140000";  -- /* socket */

  ISUID  = o"004000";  -- /* set user id on execution */
  ISGID  = o"002000";  -- /* set group id on execution */
  ISTXT  = o"001000";  -- /* sticky bit */
  IRWXU  = o"000700";  -- /* RWX mask for owner */
  IRUSR  = o"000400";  -- /* R for owner */
  IWUSR  = o"000200";  -- /* W for owner */
  IXUSR  = o"000100";  -- /* X for owner */
  IRWXG  = o"000070";  -- /* RWX mask for group */
  IRGRP  = o"000040";  -- /* R for group */
  IWGRP  = o"000020";  -- /* W for group */
  IXGRP  = o"000010";  -- /* X for group */
  IRWXO  = o"000007";  -- /* RWX mask for other */
  IROTH  = o"000004";  -- /* R for other */
  IWOTH  = o"000002";  -- /* W for other */
  IXOTH  = o"000001";  -- /* X for other */
  ISVTX  = o"001000";  -- /* save swapped text even after use */
}

local DOS_FILE_ATTR = {
  NORMAL = 0x00; -- Normal file
  RDONLY = 0x01; -- Read-only file
  HIDDEN = 0x02; -- Hidden file
  SYSTEM = 0x04; -- System file
  VOLID  = 0x08; -- Volume ID
  SUBDIR = 0x10; -- Subdirectory
  ARCH   = 0x20; -- File changed since last archive
}

local bit = require "bit32"

local attr = bit.bor(
  -- UNIX
  bit.lshift( bit.bor(
    NIX_FILE_ATTR.IFREG,
    NIX_FILE_ATTR.IRUSR,
    NIX_FILE_ATTR.IWUSR,
    NIX_FILE_ATTR.IRGRP,
    0
  ), 16),
  -- DOS
  bit.bor(
    DOS_FILE_ATTR.ARCH,
    0
  )
)

print(string.format("0x%X", attr))

The question Is what appropriate format to value.
I think about table with flags.

No permissions on zipped files

Hi,

Thanks for this module.

I may have encountered an issue but I thought that I'd run it by you before I started digging into the code.

I ran the following example from the readme with the zipped filename changed to README2.md. I didn't make any other changes:

function make_reader(fname)
  local f = assert(io.open(fname, 'rb'))
  local chunk_size = 1024
  local desc = {
    istext   = true,
    isfile   = true,
    isdir    = false,
    mtime    = 1348048902, -- lfs.attributes('modification')
    exattrib = 32,         -- get from GetFileAttributesA
  }
  return desc, desc.isfile and function()
    local chunk = f:read(chunk_size)
    if chunk then return chunk end
    f:close()
  end
end

local ZipWriter = require "ZipWriter"
ZipStream = ZipWriter.new()
ZipStream:open_stream( assert(io.open('readme.zip', 'w+b')), true )
ZipStream:write('README2.md', make_reader('README.md'))
ZipStream:close()

I then ran it and tested the output file as follows:

$ lua readme.lua

$ unzip -l readme.zip
Archive:  readme.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
     2228  09-19-12 11:01   README2.md
 --------                   -------
     2228                   1 file

$ zipinfo readme.zip
Archive:  readme.zip   1151 bytes   1 file
?---------  2.0 unx     2228 t- defN 19-Sep-12 11:01 README2.md
1 file, 2228 bytes uncompressed, 1033 bytes compressed:  53.6%


$ unzip readme.zip
Archive:  readme.zip
  inflating: README2.md

$ ls -l README2.md
----------  1 John  staff  2228 19 Sep  2012 README2.md

Two things to note above. The archive information from zipinfo is blank: ?--------- and the unzipped file permissions are 0000: ----------.

For comparison, the output from a zip created by system zip looks like this:

$ zip readme_sys.zip README.md
  adding: README.md (deflated 54%)

$ zipinfo readme_sys.zip
Archive:  readme_sys.zip   1201 bytes   1 file
-rw-r--r--  3.0 unx     2228 tx defN  6-Mar-14 22:23 README.md
1 file, 2228 bytes uncompressed, 1033 bytes compressed:  53.6%

The results above are from Mac OS X but I saw the same behaviour on Ubuntu. I installed ZipWriter from luarocks. Here are lua and rock versions that I used:

$ lua -v
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio

$ luarocks list

Installed rocks:
----------------

lzlib
   0.4.work3-1 (installed) - /usr/local/lib/luarocks/rocks

struct
   1.4-1 (installed) - /usr/local/lib/luarocks/rocks

zipwriter
   0.1.2-1 (installed) - /usr/local/lib/luarocks/rocks

Regards,

John

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.