mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-11-10 23:31:04 +00:00
185 lines
3.1 KiB
Lua
185 lines
3.1 KiB
Lua
--
|
|
-- filter.lua from Lsyncd -- the Live (Mirror) Syncing Demon
|
|
--
|
|
--
|
|
-- A set of filter patterns.
|
|
--
|
|
-- Filters allow excludes and includes
|
|
--
|
|
--
|
|
--
|
|
-- License: GPLv2 (see COPYING) or any later version
|
|
-- Authors: Axel Kittenberger <axkibe@gmail.com>
|
|
--
|
|
if lsyncd_version
|
|
then
|
|
print( 'Error, Lsyncd mantle already loaded' )
|
|
os.exit( -1 )
|
|
end
|
|
|
|
|
|
--
|
|
-- Turns a rsync like file pattern to a lua pattern.
|
|
-- ( at best it can )
|
|
--
|
|
local function toLuaPattern
|
|
(
|
|
p -- the rsync like pattern
|
|
)
|
|
local o = p
|
|
|
|
p = string.gsub( p, '%%', '%%%%' )
|
|
p = string.gsub( p, '%^', '%%^' )
|
|
p = string.gsub( p, '%$', '%%$' )
|
|
p = string.gsub( p, '%(', '%%(' )
|
|
p = string.gsub( p, '%)', '%%)' )
|
|
p = string.gsub( p, '%.', '%%.' )
|
|
p = string.gsub( p, '%[', '%%[' )
|
|
p = string.gsub( p, '%]', '%%]' )
|
|
p = string.gsub( p, '%+', '%%+' )
|
|
p = string.gsub( p, '%-', '%%-' )
|
|
p = string.gsub( p, '%?', '[^/]' )
|
|
p = string.gsub( p, '%*', '[^/]*' )
|
|
-- this was a ** before
|
|
p = string.gsub( p, '%[%^/%]%*%[%^/%]%*', '.*' )
|
|
p = string.gsub( p, '^/', '^/' )
|
|
|
|
if p:sub( 1, 2 ) ~= '^/'
|
|
then
|
|
-- if does not begin with '^/'
|
|
-- then all matches should begin with '/'.
|
|
p = '/' .. p;
|
|
end
|
|
|
|
log( 'Filter', 'toLuaPattern "', o, '" = "', p, '"' )
|
|
|
|
return p
|
|
end
|
|
|
|
--
|
|
-- Appends a filter pattern
|
|
--
|
|
local function append
|
|
(
|
|
self, -- the filters object
|
|
line -- filter line
|
|
)
|
|
local rule, pattern = string.match( line, '%s*([+|-])%s*(.*)' )
|
|
|
|
if not rule or not pattern
|
|
then
|
|
log( 'Error', 'Unknown filter rule: "', line, '"' )
|
|
terminate( -1 )
|
|
end
|
|
|
|
local lp = toLuaPattern( pattern )
|
|
|
|
table.insert( self. list, { rule = rule, pattern = pattern, lp = lp } )
|
|
end
|
|
|
|
--
|
|
-- Adds a list of patterns to filter.
|
|
--
|
|
local function appendList
|
|
(
|
|
self,
|
|
plist
|
|
)
|
|
for _, v in ipairs( plist )
|
|
do
|
|
append( self, v )
|
|
end
|
|
end
|
|
|
|
--
|
|
-- Loads the filters from a file.
|
|
--
|
|
local function loadFile
|
|
(
|
|
self, -- self
|
|
file -- filename to load from
|
|
)
|
|
f, err = io.open( file )
|
|
|
|
if not f
|
|
then
|
|
log( 'Error', 'Cannot open filter file "', file, '": ', err )
|
|
|
|
terminate( -1 )
|
|
end
|
|
|
|
for line in f:lines( )
|
|
do
|
|
if string.match( line, '^%s*#' )
|
|
or string.match( line, '^%s*$' )
|
|
then
|
|
-- a comment or empty line: ignore
|
|
else
|
|
append( self, line )
|
|
end
|
|
end
|
|
|
|
f:close( )
|
|
end
|
|
|
|
--
|
|
-- Tests if 'path' is filtered.
|
|
-- Returns false if it is to be filtered.
|
|
--
|
|
local function test
|
|
(
|
|
self, -- self
|
|
path -- the path to test
|
|
)
|
|
if path:byte( 1 ) ~= 47
|
|
then
|
|
error( 'Paths for filter tests must start with \'/\'' )
|
|
end
|
|
|
|
for _, entry in ipairs( self.list )
|
|
do
|
|
local rule = entry.rule
|
|
local lp = entry.lp -- lua pattern
|
|
|
|
if lp:byte( -1 ) == 36
|
|
then
|
|
-- ends with $
|
|
if path:match( lp )
|
|
then
|
|
return rule == '+'
|
|
end
|
|
else
|
|
-- ends either end with / or $
|
|
if path:match( lp .. '/' )
|
|
or path:match( lp .. '$' )
|
|
then
|
|
return rule == '+'
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
--
|
|
-- Cretes a new filter set.
|
|
--
|
|
local function new
|
|
( )
|
|
return {
|
|
list = { },
|
|
-- functions
|
|
append = append,
|
|
appendList = appendList,
|
|
loadFile = loadFile,
|
|
test = test,
|
|
}
|
|
end
|
|
|
|
|
|
--
|
|
-- Exported interface.
|
|
--
|
|
Filter = { new = new }
|
|
|