updated to add support for freebsd() self update

Bryan Roe committed Jan 17, 2021 at 15:11 UTC fb9c146ccc2684bf5a40b2b7f0de30ce0d3094d5
1 file changed +73 -8
agents/recoverycore.js
+73 -8
@@ -56,6 +56,63 @@ function sendAgentMessage(msg, icon)
56 require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages });
57 }
58
59 +function bsd_execv(name, agentfilename, sessionid)
60 +{
61 + var child = require('child_process').execFile('/bin/sh', ['sh']);
62 + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
63 + child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
64 + child.stdin.write("cat /usr/lib/libc.so | awk '");
65 + child.stdin.write('{');
66 + child.stdin.write(' a=split($0, tok, "(");');
67 + child.stdin.write(' if(a>1)');
68 + child.stdin.write(' {');
69 + child.stdin.write(' split(tok[2], b, ")");');
70 + child.stdin.write(' split(b[1], c, " ");');
71 + child.stdin.write(' print c[1];');
72 + child.stdin.write(' }');
73 + child.stdin.write("}'\nexit\n");
74 + child.waitExit();
75 + if (child.stdout.str.trim() == '')
76 + {
77 + if (sessionid != null) { sendConsoleText('Self Update failed because cannot find libc.so', sessionid) }
78 + sendAgentMessage('Self Update failed because cannot find libc.so', 3);
79 + return;
80 + }
81 +
82 + var libc = null;
83 + try
84 + {
85 + libc = require('_GenericMarshal').CreateNativeProxy(child.stdout.str.trim());
86 + libc.CreateMethod('execv');
87 + }
88 + catch(e)
89 + {
90 + if (sessionid != null) { sendConsoleText('Self Update failed: ' + e.toString(), sessionid) }
91 + sendAgentMessage('Self Update failed: ' + e.toString(), 3);
92 + return;
93 + }
94 +
95 + var i;
96 + var path = require('_GenericMarshal').CreateVariable(process.execPath);
97 + var argarr = [];
98 + var args;
99 + var options = require('MeshAgent').getStartupOptions();
100 + for(i in options)
101 + {
102 + argarr.push('--' + i + '="' + options[i] + '"');
103 + }
104 + args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
105 + for (i = 0; i < argarr.length; ++i)
106 + {
107 + var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
108 + arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
109 + }
110 +
111 + libc.execv(path, args);
112 + if (sessionid != null) { sendConsoleText('Self Update failed because execv() failed', sessionid) }
113 + sendAgentMessage('Self Update failed because execv() failed', 3);
114 +}
115 +
116 function windows_execve(name, agentfilename, sessionid)
117 {
118 var libc;
@@ -180,7 +237,7 @@ function agentUpdate_Start(updateurl, updateoptions)
237 }
238
239 // Send an indication to the server that we got the update download correctly.
183 - try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
240 + try { require('MeshAgent').SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
241
242 if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
243 if (process.platform == 'win32')
@@ -198,21 +255,29 @@ function agentUpdate_Start(updateurl, updateoptions)
255
256 // copy update
257 require('fs').copyFileSync(process.cwd() + agentfilename + '.update', process.execPath);
258 + require('fs').chmodSync(process.execPath, m);
259
260 // erase update
261 require('fs').unlinkSync(process.cwd() + agentfilename + '.update');
262
263 if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
206 - try
264 + if (process.platform == 'freebsd')
265 {
208 - // restart service
209 - var s = require('service-manager').manager.getService(name);
210 - s.restart();
266 + bsd_execv(name, agentfilename, sessionid);
267 }
212 - catch (zz)
268 + else
269 {
214 - sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
215 - sendAgentMessage('Self Update encountered an error trying to restart service', 3);
270 + try
271 + {
272 + // restart service
273 + var s = require('service-manager').manager.getService(name);
274 + s.restart();
275 + }
276 + catch (zz)
277 + {
278 + sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
279 + sendAgentMessage('Self Update encountered an error trying to restart service', 3);
280 + }
281 }
282 }
283 });