This file is indexed.

/usr/share/lua/5.1/sputnik/util.lua is in sputnik 12.06.27-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
-----------------------------------------------------------------------------
-- Defines utility functions for Sputnik.
--
-- (c) 2007, 2008  Yuri Takhteyev (yuri@freewisdom.org)
-- License: MIT/X, see http://sputnik.freewisdom.org/en/License
-----------------------------------------------------------------------------

module(..., package.seeall)

-----------------------------------------------------------------------------
-- Splits a string on a delimiter. 
-- Adapted from http://lua-users.org/wiki/SplitJoin.
-- 
-- @param text           the text to be split.
-- @param delimiter      the delimiter.
-- @return               unpacked values.
-----------------------------------------------------------------------------
function split(text, delimiter)
   local list = {}
   local pos = 1
   if string.find("", delimiter, 1) then 
      error("delimiter matches empty string!")
   end
   while 1 do
      local first, last = string.find(text, delimiter, pos)
      if first then -- found?
	 table.insert(list, string.sub(text, pos, first-1))
	 pos = last+1
      else
	 table.insert(list, string.sub(text, pos))
	 break
      end
   end
   return unpack(list)
end

-----------------------------------------------------------------------------
-- Escapes a text for using in a text area.
-- 			
-- @param text           the text to be escaped.
-- @return               the escaped text.
-----------------------------------------------------------------------------
function escape(text) 
   text = text or ""
   text = text:gsub("&", "&amp;"):gsub(">","&gt;"):gsub("<","&lt;")
   return text:gsub("\"", "&quot;")
end

-----------------------------------------------------------------------------
-- Escapes a URL.
-- 
-- @param text           the URL to be escaped.
-- @return               the escaped URL.
-----------------------------------------------------------------------------

function escape_url(text)
   return text:gsub("[^a-zA-Z0-9]",
                    function(character) 
                       return string.format("%%%x", string.byte(character))
                    end)
end

-----------------------------------------------------------------------------
-- A template for cosmo error messages.
-----------------------------------------------------------------------------
COSMO_ERROR_TEMPLATE = [[
<span style="color:red; size=200%%; font-weight: bold">
  Error in Cosmo Template:
</span><br/><br/>
<sp style="color:#660000; size=150%%; font-weight: bold">Template</p>
<pre><code>%s</code></pre>
<p style="color:#660000; size=150%%; font-weight: bold">Values</p>
<pre><code>%s</code></pre>
<p style="color:#660000; size=150%%; font-weight: bold">Message</p>
<pre><code>%s</code></pre>
]]

-----------------------------------------------------------------------------
-- Like cosmo.f() but returns an HTMLized message in case of error.
--
-- @param template       a cosmo template.
-----------------------------------------------------------------------------
function f(template)
   local fn = cosmo.f(template)
   return function(values)
      local function error_handler (err)
               local values_as_str = ""
               for k,v in pairs(values) do
                  values_as_str = values_as_str..k..": <"..type(v)..">\n"
               end
               return string.format(COSMO_ERROR_TEMPLATE, escape(template),
                                    escape(values_as_str),
                                    escape(err:gsub("\nstack traceback:.*$", "")))
      end
      local ok, result_or_error = xpcall(function() return fn(values) end,
                                         error_handler)
      return result_or_error, ok
   end
end

-----------------------------------------------------------------------------
-- Turns a string into something that can be used as a page name, converting
-- - ? + = % ' " / \ and spaces to '_'.  Note this isn't enought to ensure
-- legal win2k names, since we _are_ allowing [ ] + < > : ; *, but we'll rely
-- on versium to escape those later.
-- 
-- @param text           the string to be dirified.
-- @return               the dirified string.
-----------------------------------------------------------------------------
function dirify(text)
   local pattern = [[[%?%+%=%%%s%'%"%\]+]]
   return (text or ""):gsub(pattern, "_")
end

-----------------------------------------------------------------------------
-- Returns value1 if condition is true and value2 otherwise.  Note that if 
-- expressions are passed for value1 and value2, then they will be evaluated
-- _before_ the choice is made.
--
-- @param condition      a boolean value
-- @param value1         the value that gets returned in case of true
-- @param value2         the value that gets returned in case of false
-- @return               either value1 or value2
-----------------------------------------------------------------------------
function choose(condition, value1, value2)
   if condition then
      return value1
   else
      return value2
   end
end

-----------------------------------------------------------------------------
-- An auxiliary function for sendmail, to extract an actual email address
-- from a address field with a name.
-----------------------------------------------------------------------------
function _extract_email_address(from)
   local from_email_address
   for match in from:gmatch("[a-zA-Z]%S*@%S*[a-zA-Z]") do
      from_email_address = match
   end
   if not from_email_address then
      error("Could not find an email address in "..args.from)
   end
   return from_email_address
end

-----------------------------------------------------------------------------
-- An auxiliary function for sendmail, to collect email addresses in the
-- to, cc, and bcc fields.
--
-- @param recepients     a table for collecting results
-- @param field          the field
-----------------------------------------------------------------------------
function _collect_recepients_for_sendmail(recepients, field)
   if type(field)=="string" then     
      table.insert(recepients, "<".._extract_email_address(field)..">")
   elseif type(field)==type({}) then
      for i, addr in ipairs(field) do
         table.insert(recepients, "<".._extract_email_address(addr)..">")
      end
   else
      error("to, cc and bcc fields must be a string or a table")
   end
end

-----------------------------------------------------------------------------
-- Sends email on Sputnik's behalf.
--
-- @param args           a table of parameters
-- @param sputnik        an instance of Sputnik
-- @return               status (boolean) and possibly an error message
-----------------------------------------------------------------------------
function sendmail(args, sputnik)
   assert(args.to, "No recepient specified")
   assert(args.subject, "No subject specified")
   assert(args.from, "No source specified")

   local from_email_address = _extract_email_address(args.from)
  
   local recepients = {}
   assert(args.to, "The destination address must be specified")
   _collect_recepients_for_sendmail(recepients, args.to)
   _collect_recepients_for_sendmail(recepients, args.bcc or {})

   local smtp = require("socket.smtp")
   local status, err = smtp.send{
            from = from_email_address,
            rcpt = recepients,
            source = smtp.message{
               headers = {
                  from = args.from,
                  to = args.to,
                  subject = args.subject
               },
               body = args.body or "",
            },
            server = sputnik.config.SMTP_SERVER or "localhost",
            port   = sputnik.config.SMTP_SERVER_PORT or 25,
            user   = sputnik.config.SMTP_USER,
            password   = sputnik.config.SMTP_PASSWORD,
         }
   return status, err
end

-----------------------------------------------------------------------------
-- Creates a logger instance.
-----------------------------------------------------------------------------
function make_logger(module_name, params, level)
   if module_name then
      require("logging."..module_name)
      local logger, err = logging[module_name](unpack(params))
      assert(logger, "Could not initialize logger: "..(err or ""))
      if level then 
         require("logging")
         logger:setLevel(logging[level])
      end
      return logger
   else
      return {
         debug = function(...) end, -- do nothing
         info  = function(...) end,
         error = function(...) end,
         warn  = function(...) end,
      }
   end
end

-----------------------------------------------------------------------------
-- A cycle class.
----------------------------------------------------------------------------- 
local Cycle = {}
local Cycle_mt = {__metatable = {}, __index = Cycle}
function new_cycle(values)
   return setmetatable({values=values, i=1}, Cycle_mt)
end
function Cycle:next()
   self.i = (self.i % #(self.values)) + 1
end
function Cycle:get()
   return self.values[self.i]
end