mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-15 07:43:50 +00:00
1. Updated fs.readSync
2. Added zip-reader.isZip() 3. Added support for zip compressed selfupdate
This commit is contained in:
@@ -2470,6 +2470,59 @@ void MeshServer_SendAgentInfo(MeshAgentHostContainer* agent, ILibWebClient_State
|
||||
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
|
||||
}
|
||||
|
||||
void MeshServer_selfupdate_continue(MeshAgentHostContainer *agent)
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
agent->performSelfUpdate = 1;
|
||||
#else
|
||||
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
|
||||
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
|
||||
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
|
||||
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
|
||||
#endif
|
||||
|
||||
if (duk_peval_string_noresult(agent->meshCoreCtx, "require('service-manager').manager.getService('meshagentDiagnostic').start();") == 0)
|
||||
{
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
ILIBLOGMESSSAGE("SelfUpdate -> Starting Secondary Agent, to assist with self update");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
ILIBLOGMESSSAGE("SelfUpdate -> Secondary Agent unavailable to assist with self update");
|
||||
}
|
||||
}
|
||||
|
||||
// Everything looks good, lets perform the update
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
char tmp[255];
|
||||
sprintf_s(tmp, sizeof(tmp), "SelfUpdate -> Stopping Chain (%d)", agent->performSelfUpdate);
|
||||
ILIBLOGMESSSAGE(tmp);
|
||||
}
|
||||
ILibStopChain(agent->chain);
|
||||
}
|
||||
duk_ret_t MeshServer_selfupdate_unzip_complete(duk_context *ctx)
|
||||
{
|
||||
duk_eval_string(ctx, "require('MeshAgent')"); // [MeshAgent]
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, MESH_AGENT_PTR);
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Updated successfully unzipped..."); }
|
||||
MeshServer_selfupdate_continue(agent);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t MeshServer_selfupdate_unzip_error(duk_context *ctx)
|
||||
{
|
||||
duk_eval_string(ctx, "require('MeshAgent')"); // [MeshAgent]
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, MESH_AGENT_PTR);
|
||||
duk_push_sprintf(ctx, "SelfUpdate -> FAILED to unzip update: %s", (char*)duk_safe_to_string(ctx, 0));
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE(duk_safe_to_string(ctx, -1)); }
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Process MeshCentral server commands.
|
||||
void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent, char *cmd, int cmdLen)
|
||||
{
|
||||
@@ -2915,54 +2968,64 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
if ((GenerateSHA384FileHash(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
|
||||
{
|
||||
//printf("UPDATE: End OK\r\n");
|
||||
int updateTop = duk_get_top(agent->meshCoreCtx);
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash verified"); }
|
||||
if (agent->fakeUpdate != 0)
|
||||
{
|
||||
int fsz;
|
||||
char *fsc;
|
||||
fsz = ILibReadFileFromDiskEx(&fsc, agent->exePath);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.zip", agent->exePath);
|
||||
fsz = ILibReadFileFromDiskEx(&fsc, ILibScratchPad);
|
||||
if (fsz == 0)
|
||||
{
|
||||
fsz = ILibReadFileFromDiskEx(&fsc, agent->exePath);
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with same version..."); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with provided zip..."); }
|
||||
}
|
||||
ILibWriteStringToDiskEx(updateFilePath, fsc, fsz);
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with same version..."); }
|
||||
}
|
||||
if (agent->fakeUpdate != 0 || agent->forceUpdate != 0)
|
||||
{
|
||||
ILibSimpleDataStore_Put(agent->masterDb, "disableUpdate", "1");
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Disabling future updates..."); }
|
||||
}
|
||||
#ifdef WIN32
|
||||
agent->performSelfUpdate = 1;
|
||||
#else
|
||||
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
|
||||
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
|
||||
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
|
||||
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
|
||||
#endif
|
||||
|
||||
if (duk_peval_string_noresult(agent->meshCoreCtx, "require('service-manager').manager.getService('meshagentDiagnostic').start();") == 0)
|
||||
duk_eval_string(agent->meshCoreCtx, "require('zip-reader')"); // [reader]
|
||||
duk_prepare_method_call(agent->meshCoreCtx, -1, "isZip"); // [reader][isZip][this]
|
||||
duk_push_string(agent->meshCoreCtx, updateFilePath); // [reader][isZip][this][path]
|
||||
duk_pcall_method(agent->meshCoreCtx, 1); // [reader][boolean]
|
||||
if (duk_to_boolean(agent->meshCoreCtx, -1))
|
||||
{
|
||||
if (agent->logUpdate != 0)
|
||||
// Update File is zipped
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Unzipping update..."); }
|
||||
duk_eval_string(agent->meshCoreCtx, "require('update-helper')"); // [helper]
|
||||
duk_prepare_method_call(agent->meshCoreCtx, -1, "start"); // [helper][start][this]
|
||||
duk_push_string(agent->meshCoreCtx, updateFilePath); // [helper][start][this][path]
|
||||
if (duk_pcall_method(agent->meshCoreCtx, 1) == 0) // [helper][promise]
|
||||
{
|
||||
ILIBLOGMESSSAGE("SelfUpdate -> Starting Secondary Agent, to assist with self update");
|
||||
duk_prepare_method_call(agent->meshCoreCtx, -1, "then"); // [helper][promise][then][this]
|
||||
duk_push_c_function(agent->meshCoreCtx, MeshServer_selfupdate_unzip_complete, DUK_VARARGS);//..][res]
|
||||
duk_push_c_function(agent->meshCoreCtx, MeshServer_selfupdate_unzip_error, DUK_VARARGS);//[this][res][rej]
|
||||
duk_pcall_method(agent->meshCoreCtx, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (agent->logUpdate != 0)
|
||||
else
|
||||
{
|
||||
ILIBLOGMESSSAGE("SelfUpdate -> Secondary Agent unavailable to assist with self update");
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "SelfUpdate -> Error Unzipping: %s", duk_safe_to_string(agent->meshCoreCtx, -1));
|
||||
ILIBLOGMESSSAGE(ILibScratchPad);
|
||||
}
|
||||
}
|
||||
duk_set_top(agent->meshCoreCtx, updateTop); // ...
|
||||
break; // Break out here, and continue when finished unzipping (or in the case of error, abort)
|
||||
}
|
||||
|
||||
|
||||
// Everything looks good, lets perform the update
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
char tmp[255];
|
||||
sprintf_s(tmp, sizeof(tmp), "SelfUpdate -> Stopping Chain (%d)", agent->performSelfUpdate);
|
||||
ILIBLOGMESSSAGE(tmp);
|
||||
}
|
||||
ILibStopChain(agent->chain);
|
||||
} else
|
||||
duk_set_top(agent->meshCoreCtx, updateTop); // ...
|
||||
MeshServer_selfupdate_continue(agent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hash check failed, delete the file and do nothing. On next server reconnect, we will try again.
|
||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash FAILED, aborting update..."); }
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -407,21 +407,33 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
|
||||
{
|
||||
int narg = (int)duk_get_top(ctx);
|
||||
if (narg > 3)
|
||||
{
|
||||
// Convert to Options Format
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_prepare_method_call(ctx, -1, "readSync"); // [fs][readSync][this]
|
||||
duk_dup(ctx, 0); duk_dup(ctx, 1); // [fs][readSync][this][fd][buffer]
|
||||
duk_push_object(ctx); // [fs][readSync][this][fd][buffer][options]
|
||||
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "offset");
|
||||
duk_dup(ctx, 3); duk_put_prop_string(ctx, -2, "length");
|
||||
duk_dup(ctx, 4); duk_put_prop_string(ctx, -2, "position");
|
||||
duk_call_method(ctx, 3);
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_size_t bufferSize;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 1, &bufferSize);
|
||||
int offset = duk_require_int(ctx, 2);
|
||||
int length = duk_require_int(ctx, 3);
|
||||
int offset = Duktape_GetIntPropertyValue(ctx, 2, "offset", 0);
|
||||
int length = Duktape_GetIntPropertyValue(ctx, 2, "length", (int)bufferSize);
|
||||
int position = Duktape_GetIntPropertyValue(ctx, 2, "position", -1);
|
||||
int bytesRead;
|
||||
FILE *f = ILibDuktape_fs_getFilePtr(ctx, duk_require_int(ctx, 0));
|
||||
|
||||
if (length > (int)bufferSize) { return(ILibDuktape_Error(ctx, "fs.readSync(): Buffer of size: %llu bytes, but attempting to read %d bytes", (uint64_t)bufferSize, length)); }
|
||||
|
||||
if (f != NULL)
|
||||
{
|
||||
if (duk_is_number(ctx, 4))
|
||||
{
|
||||
fseek(f, duk_require_int(ctx, 4), SEEK_SET);
|
||||
}
|
||||
if (position >= 0) { fseek(f, position, SEEK_SET); }
|
||||
bytesRead = (int)fread(buffer + offset, 1, length, f);
|
||||
duk_push_int(ctx, bytesRead);
|
||||
return 1;
|
||||
@@ -2319,7 +2331,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "closeSync", ILibDuktape_fs_closeSync, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "openSync", ILibDuktape_fs_openSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readSync", ILibDuktape_fs_readSync, 5);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readSync", ILibDuktape_fs_readSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "writeSync", ILibDuktape_fs_writeSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_fs_read, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "write", ILibDuktape_fs_write, DUK_VARARGS);
|
||||
|
||||
@@ -438,4 +438,19 @@ function read(path)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
module.exports = { read: read };
|
||||
function isZip(path)
|
||||
{
|
||||
if (require('fs').statSync(path).size < 30) { return (false); }
|
||||
var fd = require('fs').openSync(path, 'rb');
|
||||
var jsFile = Buffer.alloc(4);
|
||||
var bytesRead = require('fs').readSync(fd, jsFile, { position: 0 });
|
||||
require('fs').closeSync(fd);
|
||||
|
||||
if (bytesRead == 4 && jsFile[0] == 0x50 && jsFile[1] == 0x4B && jsFile[2] == 0x03 && jsFile[3] == 0x04)
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
module.exports = { read: read, isZip: isZip };
|
||||
Reference in New Issue
Block a user