/
main.c
123 lines (115 loc) · 4.79 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <iup.h>
#include "jsonFile.h"
#include "nwjsBinaryCache.h"
#include "packageJsonFile.h"
#include "paths.h"
#include "strUtil.h"
#include "downloaderGui.h"
#include "update.h"
#include "appList.h"
#include "globals.h"
int _argc;
char** _argv;
packageJsonFile_t* app;
void led_load(); //Function to load the GUI; it's defined in the files generated by the ledc tool in the res/ directory.
static void freeGlobals(){
packageJson_file_free(app);
free(app);
}
//Shows an error popup with the specified text.
static int showError(char *msg){
IupOpen(&_argc, &_argv);
char *title = "nwjsmanager";
if(app && app->name)
title = app->name;
IupMessage(title, msg);
IupClose();
freeGlobals();
return EXIT_FAILURE;
}
//Determines the most recent installed nw.js version compatible with the application and launches it.
static int launch(){
semver_t* launchVersion = NULL;
semverList_t installedVersions = nwjs_binary_cache_get_versions();
printf("[nwjsmanager][DEBUG] There are %d nw.js versions installed.\n", installedVersions.count);
for(int i = 0; i < installedVersions.count; i++)
if(packageJson_file_is_nw_version_OK(app, installedVersions.items[i]) && (!launchVersion || semver_gt(installedVersions.items[i], *launchVersion)))
launchVersion = &installedVersions.items[i];
else
printf("[nwjsmanager][DEBUG] Version %d.%d.%d is not compatible.\n", installedVersions.items[i].major, installedVersions.items[i].minor, installedVersions.items[i].patch);
if(!launchVersion){
semverList_free(&installedVersions);
IupOpen(&_argc, &_argv);
led_load();
int result = downloaderGui_download();
IupClose();
if(result == DOWNLOADERGUI_SUCCESS)
return launch(); //Recursively call this function, because now the correct nw.js version has been downloaded.
else{
freeGlobals();
return 1; //This is returned to main, and thus will be the exit code.
}
}else if(_argc > 2 && strcmp(_argv[2], "--nwjsmanager-prepare") == 0){
//If --nwjsmanager-prepare is passed as 2nd argument (after package.json path), the application won't be launched (will be used by the installation scripts, where nwjsmanager is started only to setup the correct nw.js version for the application).
printf("[nwjsmanager][DEBUG] %s will be launched with nw.js v%d.%d.%d.\n", app->name, launchVersion->major, launchVersion->minor, launchVersion->patch);
freeGlobals();
return 0;
}else{
printf("[nwjsmanager][DEBUG] Launching %s with nw.js v%d.%d.%d.\n", app->name, launchVersion->major, launchVersion->minor, launchVersion->patch);
char binDirName[256];
sprintf(binDirName, "v%d.%d.%d/", launchVersion->major, launchVersion->minor, launchVersion->patch);
char *binCachePath = path_get_nwjs_cache();
char *binPath = string_concat(3, binCachePath, binDirName, NWJS_BIN_NAME);
free(binCachePath);
printf("[nwjsmanager][DEBUG] Nw.js binary path: %s.\n", binPath);
char **args = calloc(_argc + 2, sizeof(char*));
args[0] = binPath;
for(int i = 1; i < _argc; i++)
args[i] = _argv[i];
#ifdef _WIN32
args[0] = string_concat(3, "\"", args[0], "\"");
args[1] = string_concat(3, "\"", args[1], "\""); //Enclosing path to the application's directory in quotes under Windows, to avoid it to be treated as multiple arguments if it contains spaces
#endif
args[_argc + 1] = NULL;
execv(binPath, args);
//Control flow will get here only if an error occoured (othervise the process is replaced by nw)
char *err = strerror(errno);
char *errMsg = string_concat(2, "An error occoured while launching the nw binary:\n", err);
showError(errMsg);
free(errMsg);
free(args);
return -1;
}
}
int main(int argc, char **argv){
//Clean from update
char *binPath = getBinaryPath();
char *oldBinPath = string_concat(2, binPath, ".old");
remove(oldBinPath);
free(oldBinPath);
free(binPath);
//Commands to edit the list of installed nw.js applications
if(argc > 2 && strcmp(argv[1], "--install") == 0)
return appList_add(argv[2]);
else if(argc > 2 && strcmp(argv[1], "--uninstall") == 0)
return appList_remove(argv[2]);
_argc = argc; _argv = argv;
printf("[nwjsmanager][DEBUG] This is nwjsmanager v%s\n", NWJSMANAGER_VERSION);
for(int i = 0; i < argc; i++)
printf("[nwjsmanager][DEBUG] argv[%d]: %s\n", i, argv[i]);
if(argc < 2)
return showError("No application specified. Please specify on the command line the path to the directory containing the application you want to run.");
char *packageJsonPath = string_concat(2, argv[1], "/package.json");
app = malloc(sizeof(packageJsonFile_t));
if(packageJson_file_parse(packageJsonPath, app) != JSON_SUCCESS){
free(packageJsonPath);
return showError("Failed to open or parse the application's package.json file. Please reinstall the application.");
}
free(packageJsonPath);
return launch();
}