1 /*
2 * %CopyrightBegin%
3 *
4 * Copyright Ericsson AB 2003-2017. All Rights Reserved.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * %CopyrightEnd%
19 */
20 /*
21 * Some code just simply does not deserve functions :-)
22 * Dead simple installation program to set up init files etc after erlang is
23 * copied to its destination. Also to be used after a patch is applied.
24 */
25
26 #include <windows.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "init_file.h"
30
wmain(int argc,wchar_t ** argv)31 int wmain(int argc, wchar_t **argv)
32 {
33 int silent = 0;
34 int start_sasl = 0;
35 wchar_t *root = NULL;
36 int i;
37 wchar_t buffer[MAX_PATH];
38 wchar_t erts_dir[MAX_PATH];
39 wchar_t release_dir[MAX_PATH];
40 wchar_t bin_dir[MAX_PATH];
41 char *tmp;
42 char tmp_utf8[MAX_PATH*4];
43 wchar_t my_ini_filename[MAX_PATH];
44 InitFile *my_ini_file;
45 InitSection *my_ini_section;
46 char erts_version[MAX_PATH];
47 InitFile *ini_file;
48 InitSection *ini_section;
49 HANDLE module = GetModuleHandle(NULL);
50 wchar_t *binaries[] = { L"erl.exe", L"werl.exe", L"erlc.exe", L"erl_call.exe",
51 L"dialyzer.exe",
52 L"typer.exe",
53 L"escript.exe", L"ct_run.exe", NULL };
54 wchar_t *scripts[] = { L"start_clean.boot", L"start_sasl.boot", L"no_dot_erlang.boot", NULL };
55 wchar_t fromname[MAX_PATH];
56 wchar_t toname[MAX_PATH];
57 size_t converted;
58
59 for (i = 1; i < argc; ++i) {
60 switch(argv[i][0]) {
61 case L'-' :
62 switch(argv[i][1]) {
63 case L's' :
64 silent = 1;
65 break;
66 default:
67 fprintf(stderr, "Unknown command switch %S\n",
68 argv[i]);
69 exit(1);
70 }
71 break;
72 default: {
73 if (root != NULL) {
74 fprintf(stderr, "Only one root directory can be specified, "
75 "parameter %S is illegal\n",
76 argv[i]);
77 exit(1);
78 }
79 root = argv[i];
80 }
81 break;
82 }
83 }
84 if (root == NULL) {
85 if (module == NULL) {
86 fprintf(stderr, "Cannot GetModuleHandle()\n");
87 exit(1);
88 }
89
90 if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) {
91 fprintf(stderr,"Could not GetModuleFileName()\n");
92 exit(1);
93 }
94 i = wcslen(buffer) - 1;
95 while ( i >= 0 && buffer[i] != L'\\') {
96 --i;
97 }
98 if (i < 0) {
99 fprintf(stderr,"GetModuleFileName returned broken path\n");
100 exit(1);
101 }
102 buffer[i] = L'\0';
103 root = buffer;
104 }
105
106 if (!silent) {
107 char answer[100];
108 char *eol;
109 start_sasl = 1;
110 printf("Do you want a minimal startup instead of sasl [No]: ");
111 fflush(stdout);
112 if (fgets(answer,100,stdin) == NULL) {
113 fprintf(stderr, "Could not read answer from user.\n");
114 exit(1);
115 }
116 eol = strchr(answer,'\n');
117 if (eol == NULL) {
118 while (getchar() != '\n')
119 ;
120 } else {
121 *eol = '\0';
122 }
123 if ((eol = strchr(answer, '\r')) != NULL) {
124 *eol = '\0';
125 }
126 if (_stricmp(answer,"yes") == 0 || _stricmp(answer,"y") == 0) {
127 start_sasl = 0;
128 }
129 }
130 swprintf(my_ini_filename, MAX_PATH, L"%s\\Install.ini", root);
131 my_ini_file = load_init_file(my_ini_filename);
132 if (my_ini_file == NULL) {
133 fprintf(stderr,"Cannot open init file %S\n",my_ini_filename);
134 exit(1);
135 }
136
137 if ((my_ini_section = lookup_init_section(my_ini_file,"Install"))
138 == NULL) {
139 fprintf(stderr,"No [Install] section in init file %S\n",
140 my_ini_filename);
141 exit(1);
142 }
143
144 if ((tmp = lookup_init_entry(my_ini_section, "VSN")) == NULL) {
145 fprintf(stderr,"No key VSN in init file %S\n",
146 my_ini_filename);
147 exit(1);
148 }
149 strcpy(erts_version,tmp);
150
151 swprintf(erts_dir,MAX_PATH,L"%s\\erts-%S\\bin",root,erts_version);
152 if ((tmp = lookup_init_entry(my_ini_section, "SYSTEM_VSN")) == NULL) {
153 fprintf(stderr,"No key SYSTEM_VSN in init file %S\n",
154 my_ini_filename);
155 exit(1);
156 }
157 swprintf(release_dir,MAX_PATH,L"%s\\releases\\%S",root,tmp);
158
159 swprintf(bin_dir,MAX_PATH,L"%s\\bin",root);
160 CreateDirectoryW(bin_dir,NULL);
161
162 free_init_file(my_ini_file);
163
164 for (i = 0; binaries[i] != NULL; ++i) {
165 swprintf(fromname,MAX_PATH,L"%s\\%s",erts_dir,binaries[i]);
166 swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,binaries[i]);
167 if (GetFileAttributesW(fromname) == 0xFFFFFFFF) {
168 fprintf(stderr,"Could not find file %S\n",
169 fromname);
170 exit(1);
171 }
172 if (!CopyFileW(fromname,toname,FALSE)) {
173 fprintf(stderr,"Could not copy file %S to %S\n",
174 fromname,toname);
175 fprintf(stderr,"Continuing installation anyway...\n");
176 }
177 }
178
179 for (i = 0; scripts[i] != NULL; ++i) {
180 swprintf(fromname,MAX_PATH,L"%s\\%s",release_dir,scripts[i]);
181 swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,scripts[i]);
182 if (GetFileAttributesW(fromname) == 0xFFFFFFFF) {
183 fprintf(stderr,"Could not find file %S\n",
184 fromname);
185 exit(1);
186 }
187 if (!CopyFileW(fromname,toname,FALSE)) {
188 fprintf(stderr,"Could not copy file %S to %S\n",
189 fromname,toname);
190 fprintf(stderr,"Cannot continue installation, bailing out.\n");
191 exit(1);
192 }
193 }
194 if (start_sasl) {
195 swprintf(fromname,MAX_PATH,L"%s\\start_sasl.boot",bin_dir);
196 } else {
197 swprintf(fromname,MAX_PATH,L"%s\\start_clean.boot",bin_dir);
198 }
199 swprintf(toname,MAX_PATH,L"%s\\start.boot",bin_dir);
200 if (!CopyFileW(fromname,toname,FALSE)) {
201 fprintf(stderr,"Could not copy file %S to %S\n",
202 fromname,toname);
203 fprintf(stderr,"Cannot continue installation, bailing out.\n");
204 exit(1);
205 }
206
207 /* OBS!!! If the format of the init file is changed, do not forget
208 to update release_handler:write_ini_file(...) */
209 ini_file = create_init_file();
210 ini_section = create_init_section("erlang");
211 add_init_section(ini_file,ini_section);
212 WideCharToMultiByte(CP_UTF8,0,erts_dir,-1,tmp_utf8,MAX_PATH*4,NULL,NULL);
213 add_init_entry(ini_section,"Bindir",tmp_utf8);
214 add_init_entry(ini_section,"Progname","erl");
215 WideCharToMultiByte(CP_UTF8,0,root,-1,tmp_utf8,MAX_PATH*4,NULL,NULL);
216 add_init_entry(ini_section,"Rootdir",tmp_utf8);
217 swprintf(fromname,MAX_PATH,L"%s\\erl.ini",erts_dir);
218 swprintf(toname,MAX_PATH,L"%s\\erl.ini",bin_dir);
219 if (store_init_file(ini_file,fromname) != 0) {
220 fprintf(stderr,"Could not create file %S\n",
221 fromname);
222 fprintf(stderr,"Cannot continue installation, bailing out.\n");
223 exit(1);
224 }
225 if (!CopyFileW(fromname,toname,FALSE)) {
226 fprintf(stderr,"Could not copy file %S to %S\n",
227 fromname,toname);
228 fprintf(stderr,"Cannot continue installation, bailing out.\n");
229 exit(1);
230 }
231 if (!silent) {
232 printf("Erlang %s installed successfully\n", erts_version);
233 }
234 return 0;
235 }
236
237
238
239