From DONOTREPLY at icculus.org Mon Jul 2 03:28:37 2007 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 2 Jul 2007 03:28:37 -0400 Subject: r330 - trunk Message-ID: <20070702072837.13393.qmail@icculus.org> Author: icculus Date: 2007-07-02 03:28:35 -0400 (Mon, 02 Jul 2007) New Revision: 330 Modified: trunk/CMakeLists.txt Log: Minor CMake cleanup. Modified: trunk/CMakeLists.txt =================================================================== --- trunk/CMakeLists.txt 2007-06-18 21:50:50 UTC (rev 329) +++ trunk/CMakeLists.txt 2007-07-02 07:28:35 UTC (rev 330) @@ -62,12 +62,6 @@ ENDIF(BEOS) IF(UNIX) - # !!! FIXME: probably not safe long-term. - # CMake mailing list had this hack for getting rid of -rdynamic: - # http://public.kitware.com/pipermail/cmake/2006-July/010404.html - IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") - SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) - ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux") ADD_DEFINITIONS(-DPLATFORM_UNIX=1) ADD_DEFINITIONS(-DLUA_USE_POSIX=1) IF(NOT MACOSX AND NOT BEOS) @@ -97,6 +91,17 @@ IF(MOJOSETUP_GCC_HAS_STACKPROT) ADD_DEFINITIONS(-fno-stack-protector) ENDIF(MOJOSETUP_GCC_HAS_STACKPROT) + + # !!! FIXME: probably not safe long-term. + # CMake mailing list had this hack for getting rid of -rdynamic: + # http://public.kitware.com/pipermail/cmake/2006-July/010404.html + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) + SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) + ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + + # Don't use -rpath. + SET(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE) ENDIF(CMAKE_COMPILER_IS_GNUCC) TEST_BIG_ENDIAN(MOJOSETUP_IS_BIGENDIAN) From DONOTREPLY at icculus.org Mon Jul 2 03:54:47 2007 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 2 Jul 2007 03:54:47 -0400 Subject: r331 - trunk Message-ID: <20070702075447.29449.qmail@icculus.org> Author: icculus Date: 2007-07-02 03:54:42 -0400 (Mon, 02 Jul 2007) New Revision: 331 Modified: trunk/fileio.c trunk/platform.h trunk/platform_unix.c Log: Whoops, apparently stat::st_size isn't set to the string length of a symlink's linkdest, so we were misallocating buffers here for the readlink(). With that in mind, I made an platform layer abstraction for readlink() and made the unix one robust to handle when we don't know the linkdest's size (er...which is always, but readlink() isn't real helpful here either). Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2007-07-02 07:28:35 UTC (rev 330) +++ trunk/fileio.c 2007-07-02 07:54:42 UTC (rev 331) @@ -6,7 +6,6 @@ * This file written by Ryan C. Gordon. */ -#include // !!! FIXME: unix dependency for readlink(). #include // !!! FIXME: unix dependency for stat(). #include "fileio.h" @@ -415,13 +414,12 @@ else if (S_ISLNK(statbuf.st_mode)) { ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK; - ar->prevEnum.linkdest = (char *) xmalloc(statbuf.st_size + 1); - if (readlink(fullpath, ar->prevEnum.linkdest, statbuf.st_size) < 0) + ar->prevEnum.linkdest = MojoPlatform_readlink(fullpath); + if (ar->prevEnum.linkdest == NULL) { free(fullpath); return MojoArchive_dir_enumNext(ar); } // if - ar->prevEnum.linkdest[statbuf.st_size] = '\0'; } // else if else if (S_ISDIR(statbuf.st_mode)) Modified: trunk/platform.h =================================================================== --- trunk/platform.h 2007-07-02 07:28:35 UTC (rev 330) +++ trunk/platform.h 2007-07-02 07:54:42 UTC (rev 331) @@ -49,6 +49,11 @@ // syscall! Returns true if link was created, false otherwise. boolean MojoPlatform_symlink(const char *src, const char *dst); +// Read the destination from symlink (linkname). Returns a pointer +// allocated with xmalloc() containing the linkdest on success, and NULL +// on failure. The caller is responsible for freeing the returned pointer! +char *MojoPlatform_readlink(const char *linkname); + // !!! FIXME: comment me. boolean MojoPlatform_mkdir(const char *path, uint16 perms); Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2007-07-02 07:28:35 UTC (rev 330) +++ trunk/platform_unix.c 2007-07-02 07:54:42 UTC (rev 331) @@ -82,6 +82,29 @@ } // MojoPlatform_currentWorkingDir +char *MojoPlatform_readlink(const char *linkname) +{ + size_t alloclen = 16; + char *retval = NULL; + char *buf = NULL; + size_t len = -1; + + do + { + alloclen *= 2; + buf = xrealloc(buf, alloclen); + len = readlink(linkname, buf, alloclen-1); + if ( (len != -1) && (len < (alloclen-1)) ) // !error && !overflow + { + buf[len] = '\0'; // readlink() doesn't null-terminate! + retval = xrealloc(buf, len+1); // shrink it down. + } // if + } while (len >= (alloclen-1)); // loop if we need a bigger buffer. + + return retval; // caller must free() this. +} // MojoPlatform_readlink + + static void *guaranteeAllocation(void *ptr, size_t len, size_t *_alloclen) { void *retval = NULL; @@ -176,19 +199,13 @@ else if (S_ISLNK(statbuf.st_mode)) { char *newresolve = NULL; - int br = 0; - if (linkloop > 255) goto realpathInternal_failed; - linkname = (char *) xmalloc(statbuf.st_size + 1); - br = readlink(retval, linkname, statbuf.st_size); - if (br < 0) + linkname = MojoPlatform_readlink(retval); + if (linkname == NULL) goto realpathInternal_failed; - // readlink() doesn't null-terminate! - linkname[br] = '\0'; - // chop off symlink name for its cwd. retval[len] = '\0'; @@ -202,6 +219,7 @@ strcpy(retval, newresolve); free(newresolve); free(linkname); + linkname = NULL; } // else if else From DONOTREPLY at icculus.org Mon Jul 2 03:59:00 2007 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 2 Jul 2007 03:59:00 -0400 Subject: r332 - in trunk: . scripts Message-ID: <20070702075900.31313.qmail@icculus.org> Author: icculus Date: 2007-07-02 03:58:52 -0400 (Mon, 02 Jul 2007) New Revision: 332 Modified: trunk/docs.txt trunk/gui.h trunk/gui_gtkplus2.c trunk/gui_macosx.c trunk/gui_ncurses.c trunk/gui_stdio.c trunk/gui_www.c trunk/lua_glue.c trunk/scripts/mojosetup_mainline.lua Log: The promptyn* GUI interfaces now take a default (yes or no), so you can make sure people don't just click through a EULA without consciously choosing to, etc. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/docs.txt 2007-07-02 07:58:52 UTC (rev 332) @@ -779,24 +779,30 @@ Write debug info to the installation log, if logging settings permit. - MojoSetup.msgbox(str) + MojoSetup.msgbox(title, str) Show (str) to the user with a GUI message box, and wait until they click - an "OK" button. + an "OK" button. (title) is the message box's title. - MojoSetup.promptyn(str) + MojoSetup.promptyn(title, str, defval) Show (str) to the user with a GUI message box, and wait until they click either a "YES" or "NO" button. Returns true if they clicked YES, false - if they clicked "NO". + if they clicked "NO". (title) is the message box's title. + (defval) is an optional boolean value: whether the default action should + be "YES" or "NO". If (defval) isn't specified, it defaults to false. - MojoSetup.promptynan(str) + MojoSetup.promptynan(title, str, defval) Show (str) to the user with a GUI message box, and wait until they click either a "YES", "NO", "ALWAYS" or "NEVER" button. Returns the string - "yes", "no", "always", or "never". + "yes", "no", "always", or "never". (title) is the message box's title. + (defval) is an optional boolean value: whether the default action should + be "YES" or "NO" ... "always" and "never" can not be the default, since + these tend to be destructive actions that the user should consciously + choose to do. If (defval) isn't specified, it defaults to false. MojoSetup.stackwalk() Modified: trunk/gui.h =================================================================== --- trunk/gui.h 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui.h 2007-07-02 07:58:52 UTC (rev 332) @@ -69,8 +69,8 @@ boolean (*init)(void); void (*deinit)(void); void (*msgbox)(const char *title, const char *text); - boolean (*promptyn)(const char *title, const char *text); - MojoGuiYNAN (*promptynan)(const char *title, const char *text); + boolean (*promptyn)(const char *title, const char *text, boolean def); + MojoGuiYNAN (*promptynan)(const char *title, const char *text, boolean def); boolean (*start)(const char *title, const char *splash); void (*stop)(void); int (*readme)(const char *name, const uint8 *data, size_t len, @@ -109,9 +109,10 @@ static boolean MojoGui_##module##_init(void); \ static void MojoGui_##module##_deinit(void); \ static void MojoGui_##module##_msgbox(const char *title, const char *text); \ -static boolean MojoGui_##module##_promptyn(const char *t1, const char *t2); \ +static boolean MojoGui_##module##_promptyn(const char *t1, const char *t2, \ + boolean d); \ static MojoGuiYNAN MojoGui_##module##_promptynan(const char *t1, \ - const char *t2); \ + const char *t2, boolean d); \ static boolean MojoGui_##module##_start(const char *t, const char *s); \ static void MojoGui_##module##_stop(void); \ static int MojoGui_##module##_readme(const char *name, const uint8 *data, \ Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui_gtkplus2.c 2007-07-02 07:58:52 UTC (rev 332) @@ -94,7 +94,7 @@ // !!! FIXME: language. char *title = entry->xstrdup(entry->_("Stop installation")); char *text = entry->xstrdup(entry->_("Are you sure you want to stop installation?")); - if (!MojoGui_gtkplus2_promptyn(title, text)) + if (!MojoGui_gtkplus2_promptyn(title, text, false)) click_value = CLICK_NONE; free(title); free(text); @@ -215,8 +215,10 @@ } // MojoGui_gtkplus2_msgbox -static boolean MojoGui_gtkplus2_promptyn(const char *title, const char *text) +static boolean MojoGui_gtkplus2_promptyn(const char *title, const char *text, + boolean defval) { + // !!! FIXME: support defval. gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, NULL); return (rc == GTK_RESPONSE_YES); @@ -240,8 +242,10 @@ static MojoGuiYNAN MojoGui_gtkplus2_promptynan(const char *title, - const char *text) + const char *text, + boolean defval) { + // !!! FIXME: support defval. const gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, promptynanButtonCallback); switch (rc) Modified: trunk/gui_macosx.c =================================================================== --- trunk/gui_macosx.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui_macosx.c 2007-07-02 07:58:52 UTC (rev 332) @@ -127,20 +127,22 @@ } // if return retval; -} // do_promptyn +} // do_prompt -static boolean MojoGui_macosx_promptyn(const char *title, const char *text) +static boolean MojoGui_macosx_promptyn(const char *title, const char *text + boolean defval) { - return do_prompt(title, text, true, entry->_("Yes"), entry->_("No")); + return do_prompt(title, text, defval, entry->_("Yes"), entry->_("No")); } // MojoGui_macosx_promptyn static MojoGuiYNAN MojoGui_macosx_promptynan(const char *title, - const char *text) + const char *text, + boolean defval) { STUBBED("ynan"); - return MojoGui_macosx_promptyn(title, text); // !!! FIXME + return MojoGui_macosx_promptyn(title, text, defval); // !!! FIXME } // MojoGui_macosx_promptynan Modified: trunk/gui_ncurses.c =================================================================== --- trunk/gui_ncurses.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui_ncurses.c 2007-07-02 07:58:52 UTC (rev 332) @@ -640,13 +640,25 @@ } // MojoGui_ncurses_msgbox -static boolean MojoGui_ncurses_promptyn(const char *title, const char *text) +static boolean MojoGui_ncurses_promptyn(const char *title, const char *text, + boolean defval) { char *localized_yes = entry->xstrdup(entry->_("Yes")); char *localized_no = entry->xstrdup(entry->_("No")); char *buttons[] = { localized_yes, localized_no }; MojoBox *mojobox = makeBox(title, text, buttons, 2, false, true); int rc = 0; + + // set the default to "no" instead of "yes"? + if (defval == false) + { + mojobox->hoverover = 1; + drawButton(mojobox, 0); + drawButton(mojobox, 1); + wrefresh(mojobox->buttons[0]); + wrefresh(mojobox->buttons[1]); + } // if + while ((rc = upkeepBox(&mojobox, wgetch(mojobox->mainwin))) == -1) {} freeBox(mojobox, true); free(localized_yes); @@ -656,7 +668,8 @@ static MojoGuiYNAN MojoGui_ncurses_promptynan(const char *title, - const char *text) + const char *text, + boolean defval) { char *loc_yes = entry->xstrdup(entry->_("Yes")); char *loc_no = entry->xstrdup(entry->_("No")); @@ -665,6 +678,17 @@ char *buttons[] = { loc_yes, loc_always, loc_never, loc_no }; MojoBox *mojobox = makeBox(title, text, buttons, 4, false, true); int rc = 0; + + // set the default to "no" instead of "yes"? + if (defval == false) + { + mojobox->hoverover = 3; + drawButton(mojobox, 0); + drawButton(mojobox, 3); + wrefresh(mojobox->buttons[0]); + wrefresh(mojobox->buttons[3]); + } // if + while ((rc = upkeepBox(&mojobox, wgetch(mojobox->mainwin))) == -1) {} freeBox(mojobox, true); free(loc_yes); Modified: trunk/gui_stdio.c =================================================================== --- trunk/gui_stdio.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui_stdio.c 2007-07-02 07:58:52 UTC (rev 332) @@ -105,7 +105,8 @@ } // MojoGui_stdio_msgbox -static boolean MojoGui_stdio_promptyn(const char *title, const char *text) +static boolean MojoGui_stdio_promptyn(const char *title, const char *text, + boolean defval) { boolean retval = false; if (!feof(stdin)) @@ -116,6 +117,8 @@ char buf[128]; while (!getout) { + // !!! FIXME: + // We currently ignore defval and make you type out your choice. printf(entry->_("%s\n[y/n]: "), text); fflush(stdout); if (read_stdin(buf, sizeof (buf)) < 0) @@ -133,7 +136,8 @@ } // MojoGui_stdio_promptyn -static MojoGuiYNAN MojoGui_stdio_promptynan(const char *title, const char *txt) +static MojoGuiYNAN MojoGui_stdio_promptynan(const char *title, const char *txt, + boolean defval) { MojoGuiYNAN retval = MOJOGUI_NO; if (!feof(stdin)) @@ -146,6 +150,8 @@ char buf[128]; while (!getout) { + // !!! FIXME: + // We currently ignore defval and make you type out your choice. printf(entry->_("%s\n[y/n/Always/Never]: "), txt); fflush(stdout); if (read_stdin(buf, sizeof (buf)) < 0) Modified: trunk/gui_www.c =================================================================== --- trunk/gui_www.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/gui_www.c 2007-07-02 07:58:52 UTC (rev 332) @@ -742,8 +742,12 @@ } // MojoGui_www_msgbox -static boolean MojoGui_www_promptyn(const char *title, const char *text) +static boolean MojoGui_www_promptyn(const char *title, const char *text, + boolean defval) { + // !!! FIXME: + // We currently ignore defval + int i, rc; char *htmltext = htmlescape(text); const char *buttons[] = { "no", "yes" }; @@ -764,8 +768,12 @@ } // MojoGui_www_promptyn -static MojoGuiYNAN MojoGui_www_promptynan(const char *title, const char *text) +static MojoGuiYNAN MojoGui_www_promptynan(const char *title, const char *text, + boolean defval) { + // !!! FIXME: + // We currently ignore defval + int i, rc; char *htmltext = htmlescape(text); const char *buttons[] = { "no", "yes", "always", "never" }; Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/lua_glue.c 2007-07-02 07:58:52 UTC (rev 332) @@ -556,7 +556,8 @@ { const char *title = luaL_checkstring(L, 1); const char *text = luaL_checkstring(L, 2); - rc = GGui->promptyn(title, text); + const boolean defval = lua_toboolean(L, 3); + rc = GGui->promptyn(title, text, defval); } // if return retvalBoolean(L, rc); @@ -570,7 +571,8 @@ { const char *title = luaL_checkstring(L, 1); const char *text = luaL_checkstring(L, 2); - rc = GGui->promptynan(title, text); + const boolean defval = lua_toboolean(L, 3); + rc = GGui->promptynan(title, text, defval); } // if // Never localize these strings! Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2007-07-02 07:54:42 UTC (rev 331) +++ trunk/scripts/mojosetup_mainline.lua 2007-07-02 07:58:52 UTC (rev 332) @@ -366,7 +366,7 @@ if not allowoverwrite then -- !!! FIXME: language and formatting. MojoSetup.loginfo("File '" .. dest .. "' already exists.") - local ynan = MojoSetup.promptynan(_("Conflict!"), _("File already exists! Replace?")) + local ynan = MojoSetup.promptynan(_("Conflict!"), _("File already exists! Replace?"), true) if ynan == "always" then MojoSetup.forceoverwrite = true allowoverwrite = true @@ -656,7 +656,7 @@ stages[#stages+1] = function (thisstage, maxstage) local retval = MojoSetup.gui.readme(desc,fname,thisstage,maxstage) if retval == 1 then - if not MojoSetup.promptyn(desc, _("Accept this license?")) then + if not MojoSetup.promptyn(desc, _("Accept this license?"), false) then MojoSetup.fatal(_("You must accept the license before you may install")) end end From DONOTREPLY at icculus.org Mon Jul 2 05:14:54 2007 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 2 Jul 2007 05:14:54 -0400 Subject: r333 - trunk/scripts Message-ID: <20070702091454.30743.qmail@icculus.org> Author: icculus Date: 2007-07-02 05:14:48 -0400 (Mon, 02 Jul 2007) New Revision: 333 Modified: trunk/scripts/config.lua trunk/scripts/mojosetup_mainline.lua Log: Show global EULAs before READMEs, but allow per-option EULAs, too, which show at the last possible moment before installation, and can apply to specific pieces of the install. Modified: trunk/scripts/config.lua =================================================================== --- trunk/scripts/config.lua 2007-07-02 07:58:52 UTC (rev 332) +++ trunk/scripts/config.lua 2007-07-02 09:14:48 UTC (rev 333) @@ -47,20 +47,20 @@ -- Generally these return the table you pass to them, but they -- may sanitize the values, add defaults, and verify the data. - -- End User License Agreement(s). You can specify multiple files. + -- End User License Agreement(s). You can specify multiple + -- Setup.Eula sections here. -- Also, Note the "translate" call. + -- This shows up as the first thing the user sees, and must + -- agree to before anything goes forward. You could put this + -- in the base Setup.Option and they won't be shown it until + -- installation is about to start, if you would rather + -- defer this until necessary and/or show the README first. Setup.Eula { description = "My Game License", source = MojoSetup.translate("MyGame_EULA.html") }, - Setup.Eula - { - description = "Punkbuster License", - source = MojoSetup.translate("PunkBuster_EULA.html"), - }, - -- README file(s) to show and install. Setup.Readme { @@ -128,6 +128,27 @@ end }, + -- Here's an option that has it's own EULA. + Setup.Option + { + value = true, + required = false, + disabled = false, + bytes = megabytes(1), + description = "PunkBuster support", + + Setup.Eula + { + description = "Punkbuster License", + source = MojoSetup.translate("PunkBuster_EULA.html"), + }, + + Setup.File + { + source = "media://cd1/pb.zip", + }, + }, + -- Radio buttons. Setup.OptionGroup { Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2007-07-02 07:58:52 UTC (rev 332) +++ trunk/scripts/mojosetup_mainline.lua 2007-07-02 09:14:48 UTC (rev 333) @@ -631,22 +631,9 @@ end end - -- Next stage: show any READMEs. - if install.readmes ~= nil then - for k,readme in pairs(install.readmes) do - local desc = readme.description - -- !!! FIXME: pull from archive? - local fname = "data/" .. readme.source - -- (desc) and (fname) become upvalues in this function. - stages[#stages+1] = function(thisstage, maxstage) - return MojoSetup.gui.readme(desc, fname, thisstage, maxstage) - end - end - end - - -- Next stage: accept all EULAs. Never lets user step back, so they - -- either accept or reject and go to the next EULA or stage. Rejection - -- of any EULA is considered fatal. + -- Next stage: accept all global EULAs. Rejection of any EULA is considered + -- fatal. These are global EULAs for the install, per-option EULAs come + -- later. if install.eulas ~= nil then for k,eula in pairs(install.eulas) do local desc = eula.description @@ -665,6 +652,19 @@ end end + -- Next stage: show any READMEs. + if install.readmes ~= nil then + for k,readme in pairs(install.readmes) do + local desc = readme.description + -- !!! FIXME: pull from archive? + local fname = "data/" .. readme.source + -- (desc) and (fname) become upvalues in this function. + stages[#stages+1] = function(thisstage, maxstage) + return MojoSetup.gui.readme(desc, fname, thisstage, maxstage) + end + end + end + -- Next stage: let user choose install destination. -- The config file can force a destination if it has a really good reason -- (system drivers that have to go in a specific place, for example), @@ -705,15 +705,72 @@ end -- Next stage: let user choose install options. - if install.options ~= nil or install.optiongroups ~= nil then - -- (install) becomes an upvalue in this function. - stages[#stages+1] = function(thisstage, maxstage) - -- This does some complex stuff with a hierarchy of tables in C. - return MojoSetup.gui.options(install, thisstage, maxstage) + -- This may not produce a GUI stage if it decides that all options + -- are either required or disabled. + -- (install) becomes an upvalue in this function. + stages[#stages+1] = function(thisstage, maxstage) + -- This does some complex stuff with a hierarchy of tables in C. + return MojoSetup.gui.options(install, thisstage, maxstage) + end + + + -- Next stage: accept all option-specific EULAs. + -- Rejection of any EULA will put you back one stage (usually to the + -- install options), but if there is no previous stage, this becomes + -- fatal. + -- This may not produce a GUI stage if there are no selected options with + -- EULAs to accept. + stages[#stages+1] = function(thisstage, maxstage) + local option_eulas = {} + + local function find_option_eulas(opts) + local options = opts['options'] + if options ~= nil then + for k,v in pairs(options) do + if v.value and v.eulas then + for ek,ev in pairs(v.eulas) do + option_eulas[#option_eulas+1] = ev + end + find_option_eulas(v) + end + end + end + + local optiongroups = opts['optiongroups'] + if optiongroups ~= nil then + for k,v in pairs(optiongroups) do + if not v.disabled then + find_option_eulas(v) + end + end + end end + + find_option_eulas(install) + + for k,eula in pairs(option_eulas) do + local desc = eula.description + local fname = "data/" .. eula.source + local retval = MojoSetup.gui.readme(desc,fname,thisstage,maxstage) + if retval == 1 then + if not MojoSetup.promptyn(desc, _("Accept this license?"), false) then + -- can't go back? We have to die here instead. + if thisstage == 1 then + MojoSetup.fatal(_("You must accept the license before you may install")) + else + retval = -1 -- just step back a stage. + end + end + end + + if retval ~= 1 then + return retval + end + end + + return 1 -- all licenses were agreed to. Go to the next stage. end - -- Next stage: Make sure source list is sane. -- This is not a GUI stage, it just needs to run between them. -- This gets a little hairy. From DONOTREPLY at icculus.org Mon Jul 2 05:27:01 2007 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 2 Jul 2007 05:27:01 -0400 Subject: r334 - trunk Message-ID: <20070702092701.6128.qmail@icculus.org> Author: icculus Date: 2007-07-02 05:27:00 -0400 (Mon, 02 Jul 2007) New Revision: 334 Modified: trunk/docs.txt Log: Updated documentation. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2007-07-02 09:14:48 UTC (rev 333) +++ trunk/docs.txt 2007-07-02 09:27:00 UTC (rev 334) @@ -308,49 +308,54 @@ (!!! FIXME) This attribute is for future expansion. - Setup.Readme: + Setup.Eula: - This element is a child of Setup.Package. It can be used to display a - information about the package to the end user, such as a welcome message, - FAQs, or other orientation information. There can be multiple Setup.Readme - elements listed, in which case the end user will be shown each readme - individually before installation may proceed. The readmes are shown first - before any other interaction occurs. + This element can be a child of Setup.Package or Setup.Option. It can be + used to display a license agreement to the end user, which they must agree + to before installation can proceed. If they refuse the license, the installer + terminates without installing anything (or, in the Setup.Option case, steps + back in the installation to let them change options, so they can disable the + installation of whatever they disagree with). There can be multiple + Setup.Eula elements listed, in which case the end user will be asked to + agree to each license individually before installation may proceed. The + Setup.Package licenses are shown first before any other interaction occurs, + and the Setup.Option licenses are shown after the user selects her install + options. - Setup.Readme attributes: + Setup.Eula attributes: description (no default, mustExist, mustBeString, cantBeEmpty) - This is a brief description of the Readme, used for title bars and such. + This is a brief description of the license, used for title bars and such. source (no default, mustExist, mustBeString, cantBeEmpty) This is a filename in the Base Archive's "data" directory that contains - the readme text. Currently this must be a text file in UTF-8 encoding. + the license text. Currently this must be a text file in UTF-8 encoding. - Setup.Eula: + Setup.Readme: This element is a child of Setup.Package. It can be used to display a - license agreement to the end user, which they must agree to before - installation can proceed. If they refuse the license, the installer - terminates without installing anything. There can be multiple Setup.Eula - elements listed, in which case the end user will be asked to agree to - each license individually before installation may proceed. The licenses are - shown after any readme elements. + information about the package to the end user, such as a welcome message, + FAQs, or other orientation information. There can be multiple Setup.Readme + elements listed, in which case the end user will be shown each readme + individually before installation may proceed. The readmes are shown after + any EULA elements in the Setup.Package. EULA elements in a Setup.Option + are shown later, however. - Setup.Eula attributes: + Setup.Readme attributes: description (no default, mustExist, mustBeString, cantBeEmpty) - This is a brief description of the license, used for title bars and such. + This is a brief description of the Readme, used for title bars and such. source (no default, mustExist, mustBeString, cantBeEmpty) This is a filename in the Base Archive's "data" directory that contains - the license text. Currently this must be a text file in UTF-8 encoding. + the readme text. Currently this must be a text file in UTF-8 encoding. Setup.Media: