r284 - in trunk: . scripts
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Fri May 18 12:35:55 EDT 2007
Author: icculus
Date: 2007-05-18 12:35:55 -0400 (Fri, 18 May 2007)
New Revision: 284
Modified:
trunk/docs.txt
trunk/fileio.c
trunk/lua_glue.c
trunk/platform.h
trunk/platform_unix.c
trunk/scripts/mojosetup_init.lua
trunk/scripts/mojosetup_mainline.lua
Log:
Permissions support...let mkdir set permissions, and let config file specify
file/dir permissions.
Modified: trunk/docs.txt
===================================================================
--- trunk/docs.txt 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/docs.txt 2007-05-18 16:35:55 UTC (rev 284)
@@ -157,6 +157,7 @@
mustBeFunction: Error if isn't a function (can be C or Lua).
mustBeNumber: Error if isn't a number.
mustBeUrl: Error if isn't a string that matches the regexp "^.+://.-/.*".
+ mustBePerms: Error if isn't a valid permissions string for the platform.
mustBeStringOrTableOfStrings: Error if isn't a string or an array of strings.
Attributes that aren't explicitly specified take on their default value. In
@@ -576,7 +577,21 @@
return dest -- everything else can go through as-is.
end
+ Filters can optionally return a second argument, a string, that defines
+ the destination file's permissions. This can be omitted, or nil, to use
+ the default permissions:
+ filter = function(dest)
+ if dest == "mygame-binary" then
+ return dest, "0755" -- make sure it's executable.
+ end
+ return dest -- everything else just goes through as-is.
+ end
+
+ Please see the documentation for Setup.File's "permissions" attribute for
+ further discussion.
+
+
allowoverwrite (no default, mustBeBool)
If true, the installer will overwrite existing files without warning. If
@@ -587,6 +602,34 @@
They are deleted only after a successful install.
+ permissions (no default, mustBePerms)
+
+ Override the permissions that these files will be created with. This is
+ a string for future expansion (non-Unix systems, extended attributes, etc),
+ and since Lua does not have syntax for specifying octal numbers directly.
+
+ Currently this string maps to Unix permissions as an octal number:
+ "0644" would be read/write access for the user, and read-only for the
+ group and everyone else.
+
+ If not specified, the permissions will be set to whatever is already
+ associated with the file (such as the Unix permissions in a .tar file's
+ entry).
+
+ Please note that files coming from a real filesystem will have their
+ defaults overridden by the installer (to "0644"), since operating systems
+ tend to report every file on a CD-ROMs as read-only and executable on some
+ Unix systems. Plan accordingly.
+
+ You can return a permissions string as the second value from your filter
+ function as well, which may be more efficient if you only need to change
+ a few files, as each Setup.File has to iterate the whole archive, or need
+ to adjust permissions in only a portion of a downloaded archive. This
+ attribute applies permissions to ever installed file through this element.
+ If this attribute is set and the filter returns a non-nil permission, the
+ filter takes precedence.
+
+
Add any localized strings:
If you added strings to the installer or your config file that you want
Modified: trunk/fileio.c
===================================================================
--- trunk/fileio.c 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/fileio.c 2007-05-18 16:35:55 UTC (rev 284)
@@ -387,11 +387,11 @@
{
ar->prevEnum.filesize = statbuf.st_size;
- // !!! FIXME: not sure this is the best thing.
// We currently force the perms from physical files, since CDs on
// Linux tend to mark every files as executable and read-only. If you
// want to install something with specific permissions, wrap it in a
- // tarball or chmod it from a postinstall hook in your config file.
+ // tarball, or use Setup.File.permissions, or return a permissions
+ // string from Setup.File.filter.
//ar->prevEnum.perms = statbuf.st_mode;
ar->prevEnum.perms = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Modified: trunk/lua_glue.c
===================================================================
--- trunk/lua_glue.c 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/lua_glue.c 2007-05-18 16:35:55 UTC (rev 284)
@@ -673,18 +673,37 @@
{
MojoArchive *archive = (MojoArchive *) lua_touserdata(L, 1);
const char *path = luaL_checkstring(L, 2);
+ uint16 perms = archive->prevEnum.perms;
boolean retval = false;
MojoInput *in = archive->openCurrentEntry(archive);
if (in != NULL)
{
- retval = MojoInput_toPhysicalFile(in, path, archive->prevEnum.perms,
- writeCallback, L);
+ if (!lua_isnil(L, 3))
+ {
+ boolean valid = false;
+ const char *permstr = luaL_checkstring(L, 3);
+ perms = MojoPlatform_makePermissions(permstr, &valid);
+ if (!valid)
+ fatal(_("BUG: '%s' is not a valid permission string"), permstr);
+ } // if
+ retval = MojoInput_toPhysicalFile(in, path, perms, writeCallback, L);
} // if
return retvalBoolean(L, retval);
} // luahook_writefile
+static int luahook_isvalidperms(lua_State *L)
+{
+ boolean valid = false;
+ const char *permstr = NULL;
+ if (!lua_isnil(L, 1))
+ permstr = luaL_checkstring(L, 1);
+ MojoPlatform_makePermissions(permstr, &valid);
+ return retvalBoolean(L, valid);
+} // luahook_isvalidperms
+
+
static int luahook_download(lua_State *L)
{
boolean retval = false;
@@ -811,7 +830,18 @@
static int luahook_platform_mkdir(lua_State *L)
{
const char *dir = luaL_checkstring(L, 1);
- return retvalBoolean(L, MojoPlatform_mkdir(dir));
+ uint16 perms = 0;
+ if (lua_isnil(L, 2))
+ perms = MojoPlatform_defaultDirPerms();
+ else
+ {
+ boolean valid = false;
+ const char *permstr = luaL_checkstring(L, 2);
+ perms = MojoPlatform_makePermissions(permstr, &valid);
+ if (!valid)
+ fatal(_("BUG: '%s' is not a valid permission string"), permstr);
+ } // if
+ return retvalBoolean(L, MojoPlatform_mkdir(dir, perms));
} // luahook_platform_mkdir
@@ -1330,6 +1360,7 @@
set_cfunc(luaState, luahook_wildcardmatch, "wildcardmatch");
set_cfunc(luaState, luahook_truncatenum, "truncatenum");
set_cfunc(luaState, luahook_date, "date");
+ set_cfunc(luaState, luahook_isvalidperms, "isvalidperms");
// Set some information strings...
lua_newtable(luaState);
Modified: trunk/platform.h
===================================================================
--- trunk/platform.h 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/platform.h 2007-05-18 16:35:55 UTC (rev 284)
@@ -47,7 +47,7 @@
boolean MojoPlatform_symlink(const char *src, const char *dst);
// !!! FIXME: comment me.
-boolean MojoPlatform_mkdir(const char *path);
+boolean MojoPlatform_mkdir(const char *path, uint16 perms);
// Move a file to a new name. This has to be a fast (if not atomic) operation,
// so if it would require a legitimate copy to another filesystem or device,
@@ -73,6 +73,20 @@
// !!! FIXME: comment me.
char *MojoPlatform_findMedia(const char *uniquefile);
+// Convert a string into a permissions bitmask. On Unix, this is currently
+// expected to be an octal string like "0755", but may except other forms
+// in the future, and other platforms may need to interpret permissions
+// differently. (str) may be NULL for defaults, and is considered valid.
+// If (str) is not valid, return a reasonable default and set (*valid) to
+// false. Otherwise, set (*valid) to true and return the converted value.
+uint16 MojoPlatform_makePermissions(const char *str, boolean *valid);
+
+// Return a default, sane set of permissions for a newly-created file.
+uint16 MojoPlatform_defaultFilePerms(void);
+
+// Return a default, sane set of permissions for a newly-created directory.
+uint16 MojoPlatform_defaultDirPerms(void);
+
// Wrappers for Unix dlopen/dlsym/dlclose, sort of. Instead of a filename,
// these take a memory buffer for the library. If you can't load this
// directly in RAM, the platform should write it to a temporary file first,
Modified: trunk/platform_unix.c
===================================================================
--- trunk/platform_unix.c 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/platform_unix.c 2007-05-18 16:35:55 UTC (rev 284)
@@ -482,10 +482,10 @@
} // MojoPlatform_symlink
-boolean MojoPlatform_mkdir(const char *path)
+boolean MojoPlatform_mkdir(const char *path, uint16 perms)
{
// !!! FIXME: error if already exists?
- return (mkdir(path, 0755) == 0);
+ return (mkdir(path, perms) == 0);
} // MojoPlatform_mkdir
@@ -544,6 +544,37 @@
} // MojoPlatform_perms
+uint16 MojoPlatform_defaultFilePerms(void)
+{
+ return 0644;
+} // MojoPlatform_defaultFilePerms
+
+
+uint16 MojoPlatform_defaultDirPerms(void)
+{
+ return 0755;
+} // MojoPlatform_defaultDirPerms
+
+
+uint16 MojoPlatform_makePermissions(const char *str, boolean *_valid)
+{
+ uint16 retval = 0644;
+ boolean valid = true;
+ if (str != NULL)
+ {
+ char *endptr = NULL;
+ long strval = strtol(str, &endptr, 8);
+ // complete string was a valid number?
+ valid = ((*endptr == '\0') && (strval >= 0) && (strval <= 0xFFFF));
+ if (valid)
+ retval = (uint16) strval;
+ } // if
+
+ *_valid = valid;
+ return retval;
+} // MojoPlatform_makePermissions
+
+
boolean MojoPlatform_chmod(const char *fname, uint16 p)
{
return (chmod(fname, p) != -1);
Modified: trunk/scripts/mojosetup_init.lua
===================================================================
--- trunk/scripts/mojosetup_init.lua 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/scripts/mojosetup_init.lua 2007-05-18 16:35:55 UTC (rev 284)
@@ -128,6 +128,7 @@
local function schema_assert(test, fnname, elem, errstr)
if not test then
+ -- !!! FIXME: error()? localization?
error(fnname .. "::" .. elem .. " " .. errstr .. ".", 0)
end
end
@@ -209,6 +210,12 @@
end
end
+local function mustBePerms(fnname, elem, val)
+ mustBeString(fnname, elem, val)
+ local valid = MojoSetup.isvalidperms(val)
+ schema_assert(valid, fnname, elem, "Permission string is invalid")
+end
+
local function sanitize(fnname, tab, elems)
mustBeTable(fnname, "", tab)
tab._type_ = string.lower(fnname) .. "s"; -- "Eula" becomes "eulas".
@@ -412,6 +419,7 @@
{ "wildcards", nil, mustBeStringOrTableOfStrings },
{ "filter", nil, mustBeFunction },
{ "allowoverwrite", nil, mustBeBool },
+ { "permissions", nil, mustBePerms },
})
end
Modified: trunk/scripts/mojosetup_mainline.lua
===================================================================
--- trunk/scripts/mojosetup_mainline.lua 2007-05-18 16:31:04 UTC (rev 283)
+++ trunk/scripts/mojosetup_mainline.lua 2007-05-18 16:35:55 UTC (rev 284)
@@ -226,7 +226,7 @@
end
-local function install_file(path, archive, file, option)
+local function install_file(path, archive, file, option, perms)
-- Upvalued so we don't look these up each time...
local fname = string.gsub(path, "^.*/", "", 1) -- chop the dirs off...
local ptype = _("Installing") -- !!! FIXME: localization.
@@ -245,7 +245,7 @@
end
MojoSetup.installed_files[#MojoSetup.installed_files+1] = path
- if not MojoSetup.writefile(archive, path, callback) then
+ if not MojoSetup.writefile(archive, path, perms, callback) then
-- !!! FIXME: formatting!
if not keepgoing then
MojoSetup.logerror("User cancelled install during file write.")
@@ -270,9 +270,9 @@
end
-local function install_directory(path)
+local function install_directory(path, perms)
MojoSetup.installed_files[#MojoSetup.installed_files+1] = path
- if not MojoSetup.platform.mkdir(path) then
+ if not MojoSetup.platform.mkdir(path, perms) then
-- !!! FIXME: formatting
MojoSetup.logerror("Failed to create dir '" .. path .. "'")
MojoSetup.fatal(_("mkdir failed"))
@@ -291,7 +291,7 @@
if item ~= "" then
fullpath = fullpath .. "/" .. item
if not MojoSetup.platform.exists(fullpath) then
- install_directory(fullpath)
+ install_directory(fullpath, nil)
end
end
end
@@ -361,8 +361,14 @@
dest = dest .. "/" .. entdest
end
+ local perms = file.permissions -- may be nil
+
if file.filter ~= nil then
- dest = file.filter(dest)
+ local filterperms
+ dest, filterperms = file.filter(dest)
+ if filterperms ~= nil then
+ perms = filterperms
+ end
end
if dest ~= nil then -- Only install if file wasn't filtered out
@@ -370,9 +376,9 @@
if permit_write(dest, ent, file) then
install_parent_dirs(dest)
if ent.type == "file" then
- install_file(dest, archive, file, option)
+ install_file(dest, archive, file, option, perms)
elseif ent.type == "dir" then
- install_directory(dest)
+ install_directory(dest, perms)
elseif ent.type == "symlink" then
install_symlink(dest, ent.linkdest)
else -- !!! FIXME: device nodes, etc...
More information about the mojosetup-commits
mailing list