1 | --
|
---|
2 | -- fstab.lua
|
---|
3 | --
|
---|
4 | -- $Id$
|
---|
5 | --
|
---|
6 | -- Lua 5.2 module providing a mingw-get setup hook for the MSYS fstab.
|
---|
7 | --
|
---|
8 | -- Written by Keith Marshall <keithmarshall@users.sourceforge.net>
|
---|
9 | -- Copyright (C) 2014, 2015, MinGW.org Project
|
---|
10 | --
|
---|
11 | --
|
---|
12 | -- Permission is hereby granted, free of charge, to any person obtaining a
|
---|
13 | -- copy of this software and associated documentation files (the "Software"),
|
---|
14 | -- to deal in the Software without restriction, including without limitation
|
---|
15 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
---|
16 | -- and/or sell copies of the Software, and to permit persons to whom the
|
---|
17 | -- Software is furnished to do so, subject to the following conditions:
|
---|
18 | --
|
---|
19 | -- The above copyright notice and this permission notice shall be included
|
---|
20 | -- in all copies or substantial portions of the Software.
|
---|
21 | --
|
---|
22 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
23 | -- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
24 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
25 | -- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
26 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
---|
27 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
---|
28 | -- DEALINGS IN THE SOFTWARE.
|
---|
29 | --
|
---|
30 | --
|
---|
31 | -- We begin by initializing a container, for construction of a Lua module
|
---|
32 | -- to encapsulate the content of this source file.
|
---|
33 | --
|
---|
34 | local M = {}
|
---|
35 | --
|
---|
36 | -- mingw-get passes the MSYS installation root directory path,
|
---|
37 | -- in the $MSYS_SYSROOT environment variable; from this, we deduce
|
---|
38 | -- the path name for the working copy of the fstab file...
|
---|
39 | --
|
---|
40 | local function syspath( varname )
|
---|
41 | --
|
---|
42 | -- ...using this local helper function to ensure that the path name
|
---|
43 | -- string, returned from the environment, is free from insignificant
|
---|
44 | -- trailing directory name separators, and that all internal sequences
|
---|
45 | -- of directory name separators are normalized to a single '/'.
|
---|
46 | --
|
---|
47 | local pathname = string.gsub( os.getenv( varname ), "[/\\]+", "/" )
|
---|
48 | return string.match( pathname, "(.*[^/])/*$" )
|
---|
49 | end
|
---|
50 | local sysroot = syspath( "MSYS_SYSROOT" )
|
---|
51 | local mingw32_sysroot = syspath( "MINGW32_SYSROOT" )
|
---|
52 | local fstab_file_name = sysroot .. "/etc/fstab"
|
---|
53 | --
|
---|
54 | -- The following may be adjusted, to control the layout of the mount
|
---|
55 | -- point mapping records, within the fstab file.
|
---|
56 | --
|
---|
57 | local path_name_field_width, tab_width = 40, 8
|
---|
58 | --
|
---|
59 | -- Define a template, from which a sample fstab file for the current
|
---|
60 | -- MSYS installation may be generated, on invocation of this module's
|
---|
61 | -- "dump_sample" method...
|
---|
62 | --
|
---|
63 | local fstab_sample =
|
---|
64 | { '# /etc/fstab.sample -- sample mount table configuration for MSYS.',
|
---|
65 | '',
|
---|
66 | '# Lines with a "#" in column one are interpreted as comment lines;',
|
---|
67 | '# with the exception of comments described as "magic", neither these',
|
---|
68 | '# lines, nor any blank lines, are interpreted as configuration.',
|
---|
69 | '',
|
---|
70 | '# Comment lines which are described as "magic" should neither be',
|
---|
71 | '# deleted, nor edited manually; ignoring this advice may cause your',
|
---|
72 | '# MSYS installation to malfunction.',
|
---|
73 | '',
|
---|
74 | '# When running MSYS from a portable device, such as a USB thumb drive,',
|
---|
75 | '# the following "magic" comment is used to track changes in host drive',
|
---|
76 | '# letter assignment, so allowing MSYS-Portable start-up hooks to remap',
|
---|
77 | '# mount table entries which refer to the relocated device:',
|
---|
78 | '#',
|
---|
79 | '# MSYSROOT=D:/PortableApps/MSYS/1.0',
|
---|
80 | '',
|
---|
81 | '# The mount table configuration follows below. The line format is',
|
---|
82 | '# simple: you specify the Win32 path, followed by one or more space or',
|
---|
83 | '# tab delimiters, followed by the mount point name. In a typical UNIX',
|
---|
84 | '# installation, each mount point must exist as a named directory on a',
|
---|
85 | '# physically accessible device, before it can actually be used as a',
|
---|
86 | '# mount point. For this implementation the "must exist" requirement',
|
---|
87 | '# is not enforced; however, it will assist programs such as find, and',
|
---|
88 | "# readline's tab completion if each does physically exist.",
|
---|
89 | '',
|
---|
90 | '# Win32_Path Mount_Point',
|
---|
91 | '#------------------------------------- -----------',
|
---|
92 | 'c:/mingw /mingw'
|
---|
93 | }
|
---|
94 | --
|
---|
95 | -- ...and a further template for a working configuration.
|
---|
96 | --
|
---|
97 | local fstab_basic =
|
---|
98 | { '# /etc/fstab -- mount table configuration for MSYS.',
|
---|
99 | '# Please refer to /etc/fstab.sample for explanatory annotation.',
|
---|
100 | '',
|
---|
101 | '# MSYS-Portable needs this "magic" comment:',
|
---|
102 | '# MSYSROOT=D:/PortableApps/MSYS/1.0',
|
---|
103 | '',
|
---|
104 | '# Win32_Path Mount_Point',
|
---|
105 | '#------------------------------------- -----------',
|
---|
106 | 'c:/mingw /mingw'
|
---|
107 | }
|
---|
108 | --
|
---|
109 | -- Define Lua regular expressions which may be used to identify
|
---|
110 | -- comment lines within the fstab file; (the first will match any
|
---|
111 | -- comment, while the second is specific to the "magic" comment,
|
---|
112 | -- as used by MSYS-Portable, to track changes in the allocation
|
---|
113 | -- of the drive identifier for the host device).
|
---|
114 | --
|
---|
115 | local fstab_comment_line = "^#"
|
---|
116 | local fstab_device_magic = "^(#%s*MSYSROOT=)(%S*)"
|
---|
117 | --
|
---|
118 | local function map_root_device( assignment )
|
---|
119 | --
|
---|
120 | -- A function to update the "magic" comment, which records the
|
---|
121 | -- allocation of the MSYS-Portable host device.
|
---|
122 | --
|
---|
123 | return string.gsub( assignment, fstab_device_magic, "%1" .. sysroot )
|
---|
124 | end
|
---|
125 | --
|
---|
126 | -- Define a Lua regular expression which may be used to verify
|
---|
127 | -- that any fstab file record represents a well formed mount point
|
---|
128 | -- specification; it also incorporates capture fields, which may
|
---|
129 | -- be used to extract each of the path name and mount point
|
---|
130 | -- identification fields from the specification.
|
---|
131 | --
|
---|
132 | local fstab_mount_specification = "^%s*(%S+)%s+(%S+)%s*$"
|
---|
133 | --
|
---|
134 | local function is_mount_specification( line )
|
---|
135 | --
|
---|
136 | -- A function to verify any fstab file record against the
|
---|
137 | -- preceding regular expression, to confirm whether it does
|
---|
138 | -- represent a well formed mount point specification.
|
---|
139 | --
|
---|
140 | return string.match( line, fstab_mount_specification )
|
---|
141 | end
|
---|
142 | --
|
---|
143 | local function get_mapped_path( specification )
|
---|
144 | --
|
---|
145 | -- A function to extract the associated path name field from
|
---|
146 | -- any well formed mount point specification record.
|
---|
147 | --
|
---|
148 | return string.gsub( specification, fstab_mount_specification, "%1" )
|
---|
149 | end
|
---|
150 | --
|
---|
151 | local function get_mount_point( specification )
|
---|
152 | --
|
---|
153 | -- A function to extract the mount point identification field
|
---|
154 | -- from any well formed mount point specification record.
|
---|
155 | --
|
---|
156 | return string.gsub( specification, fstab_mount_specification, "%2" )
|
---|
157 | end
|
---|
158 | --
|
---|
159 | -- In the event that a mount table configuration has already been
|
---|
160 | -- specified for this installation, capture this into an internal
|
---|
161 | -- "as built" configuration table...
|
---|
162 | --
|
---|
163 | local fstab_as_built = {}
|
---|
164 | local fstab = io.open( fstab_file_name )
|
---|
165 | if fstab
|
---|
166 | then
|
---|
167 | --
|
---|
168 | -- ...reading the existing configuration file, line by line...
|
---|
169 | --
|
---|
170 | for line in fstab:lines()
|
---|
171 | do
|
---|
172 | --
|
---|
173 | -- ...identifying comment lines...
|
---|
174 | --
|
---|
175 | if string.match( line, fstab_comment_line )
|
---|
176 | then
|
---|
177 | --
|
---|
178 | -- ...and ignoring all such, except any "device magic" line...
|
---|
179 | --
|
---|
180 | if string.match( line, fstab_device_magic )
|
---|
181 | then
|
---|
182 | --
|
---|
183 | -- ...from which we retrieve, and subsequently update, the
|
---|
184 | -- configuration-specific "sysroot" identification.
|
---|
185 | --
|
---|
186 | sysroot = string.gsub( line, fstab_device_magic, "%2" )
|
---|
187 | end
|
---|
188 | --
|
---|
189 | -- Also identify mount point specification lines...
|
---|
190 | --
|
---|
191 | elseif is_mount_specification( line )
|
---|
192 | then
|
---|
193 | if string.match( get_mount_point( line ), "^/mingw$" )
|
---|
194 | then
|
---|
195 | --
|
---|
196 | -- ...and preserve the user's pre-configured path assignment
|
---|
197 | -- for the "/mingw" mount point, if any.
|
---|
198 | --
|
---|
199 | mingw32_sysroot = get_mapped_path( line )
|
---|
200 | --
|
---|
201 | else
|
---|
202 | --
|
---|
203 | -- ...while, for all EXCEPT the "/mingw" mount point,
|
---|
204 | -- simply record the configuration.
|
---|
205 | --
|
---|
206 | table.insert( fstab_as_built, line )
|
---|
207 | end
|
---|
208 | end
|
---|
209 | end
|
---|
210 | end
|
---|
211 | --
|
---|
212 | --
|
---|
213 | local function fstab_write_configuration( fstab, template, current )
|
---|
214 | --
|
---|
215 | -- A function to write an fstab configuration to a designated output
|
---|
216 | -- stream, based on a specified template, reproducing and encapsulating
|
---|
217 | -- any existing configuration which may also have been specified...
|
---|
218 | --
|
---|
219 | local function fstab_writeln( line )
|
---|
220 | --
|
---|
221 | -- ...using this helper function to write line by line.
|
---|
222 | --
|
---|
223 | fstab:write( line .. "\n" )
|
---|
224 | end
|
---|
225 | --
|
---|
226 | local function assign_mount_point( mapped_path, mount_point )
|
---|
227 | --
|
---|
228 | -- This helper function formats each mount point specification
|
---|
229 | -- into a neatly tabulated layout...
|
---|
230 | --
|
---|
231 | local filled = string.len( mapped_path )
|
---|
232 | repeat
|
---|
233 | mapped_path, filled = mapped_path .. "\t", filled + tab_width
|
---|
234 | until filled >= path_name_field_width
|
---|
235 | --
|
---|
236 | -- ...to be written out, with one line per mount point.
|
---|
237 | --
|
---|
238 | fstab_writeln( mapped_path .. mount_point )
|
---|
239 | end
|
---|
240 | --
|
---|
241 | -- Process the template, line by line...
|
---|
242 | --
|
---|
243 | for ref, line in next, template
|
---|
244 | do
|
---|
245 | -- ...and for each comment, or blank line encountered...
|
---|
246 | --
|
---|
247 | if string.match( line, "^#" ) or string.match( line, "^%s*$" )
|
---|
248 | then
|
---|
249 | -- ...simply reproduce it in the output stream, while taking
|
---|
250 | -- care to update any "device magic" which it may incorporate,
|
---|
251 | -- so that it fits the configuration of this installation.
|
---|
252 | --
|
---|
253 | fstab_writeln( map_root_device( line ) )
|
---|
254 | --
|
---|
255 | -- When we encounter a mount point specification line -- for
|
---|
256 | -- which each of the embedded templates should include exactly
|
---|
257 | -- one example...
|
---|
258 | --
|
---|
259 | elseif is_mount_specification( line )
|
---|
260 | then
|
---|
261 | -- ...write out the specification for the "/mingw" mount
|
---|
262 | -- point, as appropriate for this installation.
|
---|
263 | --
|
---|
264 | assign_mount_point( mingw32_sysroot, "/mingw" )
|
---|
265 | end
|
---|
266 | end
|
---|
267 | --
|
---|
268 | -- And finally...
|
---|
269 | --
|
---|
270 | if current
|
---|
271 | then
|
---|
272 | -- ...when inclusion of the current mount configuration has been
|
---|
273 | -- specified, we process each configuration record in turn...
|
---|
274 | --
|
---|
275 | for ref, line in next, current
|
---|
276 | do
|
---|
277 | -- ...and write out its corresponding mount point specification,
|
---|
278 | -- (noting that we have already excluded the "/mingw" mount point
|
---|
279 | -- from the recorded configuration, but we have already written a
|
---|
280 | -- specification record for it).
|
---|
281 | --
|
---|
282 | assign_mount_point( get_mapped_path( line ), get_mount_point( line ) )
|
---|
283 | end
|
---|
284 | end
|
---|
285 | end
|
---|
286 | --
|
---|
287 | --
|
---|
288 | function M.pathname( suffix )
|
---|
289 | --
|
---|
290 | -- An exported utility function, to facilitate identification of
|
---|
291 | -- the full MS-Windows path name for the "/etc/fstab" configuration
|
---|
292 | -- file, as appropriate to the current installation...
|
---|
293 | --
|
---|
294 | if suffix
|
---|
295 | then
|
---|
296 | -- ...appending any suffix which may have been specified, (e.g.
|
---|
297 | -- to specify a reference to the "/etc/fstab.sample" file)...
|
---|
298 | --
|
---|
299 | return fstab_file_name .. suffix
|
---|
300 | end
|
---|
301 | --
|
---|
302 | -- ...otherwise, specifying a reference to "/etc/fstab" itself.
|
---|
303 | --
|
---|
304 | return fstab_file_name
|
---|
305 | end
|
---|
306 | --
|
---|
307 | --
|
---|
308 | function M.dump_sample( stream_file )
|
---|
309 | --
|
---|
310 | -- An exported utility function, providing a method for displaying,
|
---|
311 | -- or otherwise emitting suitable content for the "/etc/fstab.sample"
|
---|
312 | -- file, as directed by the embedded "fstab_sample" template...
|
---|
313 | --
|
---|
314 | if not stream_file
|
---|
315 | then
|
---|
316 | -- ...writing to "stdout", in the event that no other destination
|
---|
317 | -- has been specified.
|
---|
318 | --
|
---|
319 | stream_file = io.stdout
|
---|
320 | end
|
---|
321 | --
|
---|
322 | -- Regardless of output destination, we delegate output to this local
|
---|
323 | -- function, processing the integral sample file template, but we omit
|
---|
324 | -- the current mount table configuration.
|
---|
325 | --
|
---|
326 | fstab_write_configuration( stream_file, fstab_sample )
|
---|
327 | end
|
---|
328 | --
|
---|
329 | --
|
---|
330 | function M.initialize( stream_file )
|
---|
331 | --
|
---|
332 | -- The primary initialization function, exported for use by mingw-get,
|
---|
333 | -- to write a working mount table configuration to the specified file
|
---|
334 | -- stream, which, unless otherwise specified...
|
---|
335 | --
|
---|
336 | local default_stream_file = nil
|
---|
337 | if not stream_file
|
---|
338 | then
|
---|
339 | -- ...is to be directed to the default "/etc/fstab" file.
|
---|
340 | --
|
---|
341 | default_stream_file = io.open( fstab_file_name, "w" )
|
---|
342 | stream_file = default_stream_file
|
---|
343 | end
|
---|
344 | --
|
---|
345 | -- Once again, regardless of how the output file has been identified,
|
---|
346 | -- provided the stream has been successfully assigned...
|
---|
347 | --
|
---|
348 | if stream_file
|
---|
349 | then
|
---|
350 | -- ...we delegate the actual output function to the local helper,
|
---|
351 | -- this time, processing the integral working file template, and we
|
---|
352 | -- include the record of the current mount table configuration.
|
---|
353 | --
|
---|
354 | fstab_write_configuration( stream_file, fstab_basic, fstab_as_built )
|
---|
355 | end
|
---|
356 | --
|
---|
357 | -- Finally, when updating the default "/etc/fstab" configuration,
|
---|
358 | -- via a locally opened output file stream...
|
---|
359 | --
|
---|
360 | if default_stream_file
|
---|
361 | then
|
---|
362 | -- ...we must now ensure that this output stream is closed.
|
---|
363 | --
|
---|
364 | io.close( default_stream_file )
|
---|
365 | end
|
---|
366 | end
|
---|
367 | --
|
---|
368 | -- Since this source file is intended to be loaded as a Lua module, we
|
---|
369 | -- must ultimately return a reference handle for it.
|
---|
370 | --
|
---|
371 | return M
|
---|
372 | --
|
---|
373 | -- $RCSfile$: end of file */
|
---|