Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
A metric ton of work on the main install loop and all the million sup…
…port

 functions that go with it. Totally untested, and probably very broken.
 Also incomplete. I'm a little ashamed to commit this like this, but it's just
 growing out of control without going into revision control.
  • Loading branch information
icculus committed May 1, 2007
1 parent e5d7ad6 commit 19904c8
Show file tree
Hide file tree
Showing 12 changed files with 548 additions and 76 deletions.
10 changes: 5 additions & 5 deletions archive_zip.c
Expand Up @@ -1698,7 +1698,7 @@ static void MojoInput_zip_close(MojoInput *io)

// MojoArchive implementation...

static int MojoArchive_zip_entry_is_symlink(ZIPentry *entry)
static int MojoArchive_zip_entry_is_symlink(ZIPinfo *info, ZIPentry *entry)
{
if (entry->resolved == ZIP_UNRESOLVED_SYMLINK) /* gotta resolve it. */
zip_resolve(info->io, info, entry);
Expand Down Expand Up @@ -1743,13 +1743,13 @@ static const MojoArchiveEntry *MojoArchive_zip_enumNext(MojoArchive *ar)
{
if (enumall)
{
const ZIPentry *entry = &info->entries[info->enumIndex++];
ZIPentry *entry = &info->entries[info->enumIndex++];
ar->prevEnum.filename = xstrdup(entry->name);
ar->prevEnum.filesize = entry->uncompressed_size;
ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
if (entry->name[strlen(entry->name) - 1] == '/')
ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
else if (MojoArchive_zip_entry_is_symlink(entry))
else if (MojoArchive_zip_entry_is_symlink(info, entry))
{
ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK;
ar->prevEnum.linkdest = xstrdup(entry->linkdest);
Expand All @@ -1762,7 +1762,7 @@ static const MojoArchiveEntry *MojoArchive_zip_enumNext(MojoArchive *ar)
const char *dname = ar->prevEnum.basepath;
size_t dlen = strlen(dname);
size_t dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
const ZIPentry *entry = &info->entries[info->enumIndex];
ZIPentry *entry = &info->entries[info->enumIndex];
const char *e = entry->name;

// not past end of this dir?
Expand All @@ -1781,7 +1781,7 @@ static const MojoArchiveEntry *MojoArchive_zip_enumNext(MojoArchive *ar)
ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
if (ptr != NULL)
ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
else if (MojoArchive_zip_entry_is_symlink(entry))
else if (MojoArchive_zip_entry_is_symlink(info, entry))
{
ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK;
ar->prevEnum.linkdest = xstrdup(entry->linkdest);
Expand Down
28 changes: 24 additions & 4 deletions fileio.c
@@ -1,3 +1,4 @@
#include <unistd.h> // !!! FIXME: unix dependency for readlink().
#include <sys/stat.h> // !!! FIXME: unix dependency for stat().

#include "fileio.h"
Expand Down Expand Up @@ -67,19 +68,24 @@ void MojoArchive_resetEntry(MojoArchiveEntry *info, int basetoo)
} // MojoArchive_resetEntry



boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname)
// !!! FIXME: I'd rather not use a callback here, but I can't see a cleaner
// !!! FIXME: way right now...
boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname,
MojoInput_FileCopyCallback cb, void *data)
{
FILE *out = NULL;
boolean iofailure = false;
int32 br = 0;
int64 flen = 0;
int64 bw = 0;

STUBBED("mkdir first?");
STUBBED("file permissions?");

if (in == NULL)
return false;

flen = in->length(in);

STUBBED("fopen?");
MojoPlatform_unlink(fname);
out = fopen(fname, "wb");
Expand All @@ -97,10 +103,24 @@ boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname)
{
if (fwrite(scratchbuf_128k, br, 1, out) != 1)
iofailure = true;
else
{
bw += br;
if (cb != NULL)
{
int pct = -1;
if (flen > 0)
pct = ((int) (((double) bw) / ((double) flen))) * 100;
if (!cb(pct, data))
iofailure = true;
} // if
} // else
} // else
} // while

fclose(out);
if (fclose(out) != 0)
iofailure = true;

if (iofailure)
{
MojoPlatform_unlink(fname);
Expand Down
4 changes: 3 additions & 1 deletion fileio.h
Expand Up @@ -88,7 +88,9 @@ extern MojoArchive *GBaseArchive;
MojoArchive *MojoArchive_initBaseArchive(void);
void MojoArchive_deinitBaseArchive(void);

boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname);
typedef boolean (*MojoInput_FileCopyCallback)(int percent, void *data);
boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname,
MojoInput_FileCopyCallback cb, void *data);

#ifdef __cplusplus
}
Expand Down
192 changes: 181 additions & 11 deletions lua_glue.c
Expand Up @@ -257,7 +257,7 @@ boolean MojoLua_runFile(const char *basefname)

if (io != NULL)
{
char *realfname = xmalloc(strlen(entinfo->filename) + 10);
char *realfname = (char *) xmalloc(strlen(entinfo->filename) + 10);
sprintf(realfname, "@scripts/%s", entinfo->filename);
lua_pushcfunction(luaState, luahook_stackwalk);
rc = lua_load(luaState, MojoLua_reader, io, realfname);
Expand Down Expand Up @@ -494,6 +494,98 @@ static int luahook_findmedia(lua_State *L)
} // luahook_findmedia


static boolean writefile_callback(int percent, void *data)
{
printf("writefile_callback: %d percent\n", percent);
return true;
} // writefile_callback


// !!! FIXME: push this into Lua, make things fatal.
static int luahook_writefile(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
MojoArchive *archive = (MojoArchive *) lua_touserdata(L, 2);
boolean retval = false;

if (archive != NULL)
{
MojoInput *in = archive->openCurrentEntry(archive);
if (in != NULL)
{
retval = MojoInput_toPhysicalFile(in, path, writefile_callback, NULL);
in->close(in);
} // if
} // if

return retvalBoolean(L, retval);
} // luahook_writefile


static int luahook_archive_fromdir(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
lua_pushlightuserdata(L, MojoArchive_newFromDirectory(path));
return 1;
} // luahook_archive_fromdir


static int luahook_platform_unlink(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
return retvalBoolean(L, MojoPlatform_unlink(path));
} // luahook_platform_unlink


static int luahook_platform_exists(lua_State *L)
{
const char *dir = luaL_checkstring(L, 1);
const char *fname = lua_tostring(L, 2); // can be nil.
return retvalBoolean(L, MojoPlatform_exists(dir, fname));
} // luahook_platform_exists


static int luahook_platform_symlink(lua_State *L)
{
const char *src = luaL_checkstring(L, 1);
const char *dst = luaL_checkstring(L, 2);
return retvalBoolean(L, MojoPlatform_symlink(src, dst));
} // luahook_platform_symlink


static int luahook_platform_mkdir(lua_State *L)
{
const char *dir = luaL_checkstring(L, 1);
return retvalBoolean(L, MojoPlatform_mkdir(dir));
} // luahook_platform_mkdir


static int luahook_movefile(lua_State *L)
{
boolean retval = false;
const char *src = luaL_checkstring(L, 1);
const char *dst = luaL_checkstring(L, 2);
retval = MojoPlatform_rename(src, dst);
if (!retval)
{
MojoInput *in = MojoInput_newFromFile(src);
if (in != NULL)
{
retval = MojoInput_toPhysicalFile(in, dst, NULL, NULL);
in->close(in);
if (retval)
{
retval = MojoPlatform_unlink(src);
if (!retval)
MojoPlatform_unlink(dst); // oh well.
} // if
} // if
} // if

return retvalBoolean(L, retval);
} // luahook_movefile


static int luahook_gui_start(lua_State *L)
{
const char *title = luaL_checkstring(L, 1);
Expand Down Expand Up @@ -832,7 +924,7 @@ static int luahook_gui_destination(lua_State *L)
const char *str = NULL;
lua_pushinteger(L, i+1);
lua_gettable(L, 1);
str = lua_tostring(L, -1);
str = lua_tostring(L, -1); // !!! FIXME: alloca in a loop...
recommend[i] = (char *) alloca(strlen(str) + 1);
strcpy(recommend[i], str);
lua_pop(L, 1);
Expand Down Expand Up @@ -898,6 +990,7 @@ static int luahook_gui_endinstall(lua_State *L)


// Sets t[sym]=f, where t is on the top of the Lua stack.
// !!! FIXME: why is this a different naming convention?
static inline void set_cfunc(lua_State *L, lua_CFunction f, const char *sym)
{
lua_pushcfunction(luaState, f);
Expand All @@ -906,12 +999,23 @@ static inline void set_cfunc(lua_State *L, lua_CFunction f, const char *sym)


// Sets t[sym]=f, where t is on the top of the Lua stack.
// !!! FIXME: why is this a different naming convention?
static inline void set_cptr(lua_State *L, void *ptr, const char *sym)
{
lua_pushlightuserdata(luaState, ptr);
lua_setfield(luaState, -2, sym);
} // set_cfunc


// Sets t[sym]=f, where t is on the top of the Lua stack.
// !!! FIXME: why is this a different naming convention?
static inline void set_string(lua_State *L, const char *str, const char *sym)
{
lua_pushstring(luaState, str);
lua_setfield(luaState, -2, sym);
} // set_string

// !!! FIXME: why is this a different naming convention?
static inline void set_string_array(lua_State *L, int argc, const char **argv,
const char *sym)
{
Expand Down Expand Up @@ -943,6 +1047,22 @@ void MojoLua_setStringArray(int argc, const char **argv, const char *sym)
} // MojoLua_setStringArray


static const char *logLevelString(void)
{
switch (MojoLog_logLevel)
{
case MOJOSETUP_LOG_NOTHING: return "nothing";
case MOJOSETUP_LOG_ERRORS: return "errors";
case MOJOSETUP_LOG_WARNINGS: return "warnings";
case MOJOSETUP_LOG_INFO: return "info";
case MOJOSETUP_LOG_DEBUG: return "debug";
case MOJOSETUP_LOG_EVERYTHING: default: return "everything";
} // switch

return NULL; // shouldn't ever hit this.
} // logLevelString


boolean MojoLua_initLua(void)
{
const char *envr = cmdlinestr("locale", "MOJOSETUP_LOCALE", NULL);
Expand Down Expand Up @@ -977,6 +1097,8 @@ boolean MojoLua_initLua(void)

luaL_openlibs(luaState);

// !!! FIXME: I'd like to change the function name case for the lua hooks.

// Build MojoSetup namespace for Lua to access and fill in C bridges...
lua_newtable(luaState);
// Set up initial C functions, etc we want to expose to Lua code...
Expand All @@ -996,15 +1118,31 @@ boolean MojoLua_initLua(void)
set_cfunc(luaState, luahook_collectgarbage, "collectgarbage");
set_cfunc(luaState, luahook_debugger, "debugger");
set_cfunc(luaState, luahook_findmedia, "findmedia");
set_string(luaState, locale, "locale");
set_string(luaState, PLATFORM_NAME, "platform");
set_string(luaState, PLATFORM_ARCH, "arch");
set_string(luaState, ostype, "ostype");
set_string(luaState, osversion, "osversion");
set_string(luaState, GGui->name(), "ui");
set_string(luaState, GBuildVer, "buildver");
set_string(luaState, GLuaLicense, "lualicense");
set_string_array(luaState, GArgc, GArgv, "argv");
set_cfunc(luaState, luahook_writefile, "writefile");
set_cfunc(luaState, luahook_movefile, "movefile");

// Set some information strings...
lua_newtable(luaState);
set_string(luaState, locale, "locale");
set_string(luaState, PLATFORM_NAME, "platform");
set_string(luaState, PLATFORM_ARCH, "arch");
set_string(luaState, ostype, "ostype");
set_string(luaState, osversion, "osversion");
set_string(luaState, GGui->name(), "ui");
set_string(luaState, GBuildVer, "buildver");
set_string(luaState, GMojoSetupLicense, "license");
set_string(luaState, GLuaLicense, "lualicense");
set_string(luaState, logLevelString(), "loglevel");
set_string_array(luaState, GArgc, GArgv, "argv");
lua_setfield(luaState, -2, "info");

// Set the platform functions...
lua_newtable(luaState);
set_cfunc(luaState, luahook_platform_unlink, "unlink");
set_cfunc(luaState, luahook_platform_exists, "exists");
set_cfunc(luaState, luahook_platform_symlink, "symlink");
set_cfunc(luaState, luahook_platform_mkdir, "mkdir");
lua_setfield(luaState, -2, "platform");

// Set the GUI functions...
lua_newtable(luaState);
Expand All @@ -1021,6 +1159,12 @@ boolean MojoLua_initLua(void)
set_cfunc(luaState, luahook_gui_pumpinstall, "pumpinstall");
set_cfunc(luaState, luahook_gui_endinstall, "endinstall");
lua_setfield(luaState, -2, "gui");

// Set the i/o functions...
lua_newtable(luaState);
set_cfunc(luaState, luahook_archive_fromdir, "fromdir");
set_cptr(luaState, GBaseArchive, "base");
lua_setfield(luaState, -2, "archive");
lua_setglobal(luaState, MOJOSETUP_NAMESPACE);

// Set up localization table, if possible.
Expand Down Expand Up @@ -1061,6 +1205,32 @@ void MojoLua_deinitLua(void)
} // MojoLua_deinitLua



const char *GMojoSetupLicense =
"Copyright (c) 2007 Ryan C. Gordon and others.\n"
"\n"
"This software is provided 'as-is', without any express or implied warranty.\n"
"In no event will the authors be held liable for any damages arising from\n"
"the use of this software.\n"
"\n"
"Permission is granted to anyone to use this software for any purpose,\n"
"including commercial applications, and to alter it and redistribute it\n"
"freely, subject to the following restrictions:\n"
"\n"
"1. The origin of this software must not be misrepresented; you must not\n"
"claim that you wrote the original software. If you use this software in a\n"
"product, an acknowledgment in the product documentation would be\n"
"appreciated but is not required.\n"
"\n"
"2. Altered source versions must be plainly marked as such, and must not be\n"
"misrepresented as being the original software.\n"
"\n"
"3. This notice may not be removed or altered from any source distribution.\n"
"\n"
" Ryan C. Gordon <icculus@icculus.org>\n"
"\n";


const char *GLuaLicense =
"Lua:\n"
"\n"
Expand Down
4 changes: 4 additions & 0 deletions lua_glue.h
Expand Up @@ -7,9 +7,13 @@
extern "C" {
#endif

// License text for MojoSetup.
extern const char *GMojoSetupLicense;

// License text for Lua.
extern const char *GLuaLicense;


boolean MojoLua_initLua(void);
void MojoLua_deinitLua(void);
boolean MojoLua_initialized(void);
Expand Down

0 comments on commit 19904c8

Please sign in to comment.