summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/luat-iop.lua
blob: 469b7c034355fa785a4b86cac120894265f40258 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
-- filename : luat-iop.lua
-- comment  : companion to luat-lib.tex
-- author   : Hans Hagen, PRAGMA-ADE, Hasselt NL
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license  : see context related readme files

-- this paranoid stuff in web2c ... we cannot hook checks into the
-- input functions because one can always change the callback but
-- we can feed back specific patterns and paths into the next
-- mechanism

if not versions  then versions = { } end versions['luat-exe'] = 1.001

if not io.inp then io.inp = { } end
if not io.out then io.out = { } end

io.inp.blocked      = { }
io.out.blocked      = { }
io.inp.permitted    = { }
io.out.permitted    = { }
io.inp.modes        = { } -- functions
io.out.modes        = { } -- functions

io.blocked_openers  = { } -- *.open(name,method)

function io.inp.inhibit  (name) table.insert(io.inp.blocked,   name) end
function io.out.inhibit  (name) table.insert(io.out.blocked,   name) end
function io.inp.permit   (name) table.insert(io.inp.permitted, name) end
function io.out.permit   (name) table.insert(io.out.permitted, name) end

function io.register_opener(func) table.insert(io.blocked_openers,   func) end

function io.finalize_openers(func)
    if (#io.out.blocked > 0) or (#io.inp.blocked > 0) then
        do
            local open          = func
            local out_permitted = io.out.permitted
            local inp_permitted = io.inp.permitted
            local out_blocked   = io.out.blocked
            local inp_blocked   = io.inp.blocked
            return function(name,method)
                local function checked(blocked, permitted)
                    local n = string.lower(name)
                    for _,b in pairs(blocked) do
                        if string.find(n,b) then
                            for _,p in pairs(permitted) do
                                if string.find(n,p) then
                                    return true
                                end
                            end
                            return false
                        end
                    end
                    return true
                end
                if method and string.find(method,'[wa]') then
                    if #out.blocked > 0 then
                        if not checked(out_blocked, out_permitted) then
                            -- print("writing to " .. name .. " is not permitted")
                            return nil
                        end
                    end
                else
                    if #inp.blocked > 0 then
                        if not checked(inp_blocked, inp_permitted) then
                            -- print("reading from " .. name .. " is not permitted")
                            return nil
                        end
                    end
                end
                return open(name,method)
            end
        end
    else
        return func
    end
end

--~ io.inp.inhibit('^%.')
--~ io.inp.inhibit('^/etc')
--~ io.inp.inhibit('/windows/')
--~ io.inp.inhibit('/winnt/')
--~ io.inp.permit('c:/windows/wmsetup.log')

--~ io.open = io.finalize_openers(io.open)

--~ f = io.open('.tex')                   print(f)
--~ f = io.open('tufte.tex')              print(f)
--~ f = io.open('t:/sources/tufte.tex')   print(f)
--~ f = io.open('/etc/passwd')            print(f)
--~ f = io.open('c:/windows/crap.log')    print(f)
--~ f = io.open('c:/windows/wmsetup.log') print(f)

function io.set_opener_modes(i,o)
    for _,v in pairs({'inp','out'}) do
        if io[v][i] then
            io[v][i]()
        elseif io[v][string.sub(i,1,1)] then
            io[v][string.sub(i,1,1)]()
        end
    end
    io.open = io.finalize_openers(io.open)
end

function io.set_opener_modes(i,o)
    local f
    for _,v in pairs({'inp','out'}) do
        f = io[v][i] or io[v][string.sub(i,1,1)]
        if f then f() end
    end
    io.open = io.finalize_openers(io.open)
end

-- restricted

function io.inp.modes.restricted()
    io.inp.inhibit('^%.[%a]')
end
function io.out.modes.restricted()
    io.out.inhibit('^%.[%a]')
end

-- paranoid

function io.inp.modes.paranoid()
    io.inp.inhibit('.*')
    io.inp.inhibit('%.%.')
    io.inp.permit('^%./')
    io.inp.permit('[^/]')
    input.do_with_path('TEXMF',io.inp.permit)
end
function io.out.modes.paranoid()
    io.out.inhibit('.*')
    input.do_with_path('TEXMFOUTPUT',io.out.permit)
end

-- handy

function io.inp.modes.handy()
    io.inp.inhibit('%.%.')
    if os.platform == 'linux' then
        io.inp.inhibit('^/etc')
    else
        io.inp.inhibit('/windows/')
        io.inp.inhibit('/winnt/')
    end
end
function io.out.modes.handy()
    io.out.inhibit('.*')
    io.out.permit('%./')
    io.out.permit('^%./')
    io.out.permit('[^/]')
end

--~ io.set_opener_modes('p','p')
--~ io.set_opener_modes('r','r')
--~ io.set_opener_modes('h','h')