]>
Commit | Line | Data |
---|---|---|
904d24fe | 1 | /* |
31324d15 | 2 | * Copyright (c) 2000, 2001 Red Hat, Inc. |
904d24fe DD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to manage all the desktop setup, such | |
17 | as start menu, batch files, desktop icons, and shortcuts. Note | |
18 | that unlike other do_* functions, this one is called directly from | |
19 | install.cc */ | |
20 | ||
b24c88b3 RC |
21 | #if 0 |
22 | static const char *cvsid = | |
23 | "\n%%% $Id$\n"; | |
24 | #endif | |
8507f105 | 25 | |
904d24fe | 26 | #include "win32.h" |
ad09bcd9 | 27 | #include <shlobj.h> |
904d24fe DD |
28 | |
29 | #include <stdio.h> | |
30 | #include <stdlib.h> | |
31 | #include <unistd.h> | |
32 | ||
33 | #include "resource.h" | |
ef2007fd | 34 | #include "ini.h" |
904d24fe DD |
35 | #include "msg.h" |
36 | #include "state.h" | |
904d24fe | 37 | #include "dialog.h" |
ef2007fd | 38 | #include "version.h" |
a351e48c | 39 | #include "mount.h" |
904d24fe DD |
40 | |
41 | #include "port.h" | |
42 | ||
b24c88b3 | 43 | #include "mklink2.h" |
904d24fe | 44 | |
bb849dbd RC |
45 | #include "package_db.h" |
46 | #include "package_meta.h" | |
47 | #include "package_version.h" | |
48 | ||
3c054baf RC |
49 | #include "filemanip.h" |
50 | #include "String++.h" | |
51 | #include "io_stream.h" | |
52 | ||
ab57ceaa RC |
53 | #include "desktop.h" |
54 | ||
3c054baf | 55 | |
3a8e3956 DD |
56 | static OSVERSIONINFO verinfo; |
57 | ||
58 | /* Lines starting with '@' are conditionals - include 'N' for NT, | |
59 | '5' for Win95, '8' for Win98, '*' for all, like this: | |
60 | echo foo | |
61 | @N8 | |
62 | echo NT or 98 | |
63 | @* | |
64 | */ | |
65 | ||
b24c88b3 | 66 | static const char *etc_profile[] = { |
a6100861 | 67 | "PATH=\"/usr/local/bin:/usr/bin:/bin:$PATH\"", |
e0c3d906 | 68 | "", |
40aef45e | 69 | "USER=\"`id -un`\"", |
e0c3d906 DD |
70 | "", |
71 | "# Set up USER's home directory", | |
72 | "if [ -z \"$HOME\" ]; then", | |
40aef45e | 73 | " HOME=\"/home/$USER\"", |
e0c3d906 DD |
74 | "fi", |
75 | "", | |
40aef45e DD |
76 | "if [ ! -d \"$HOME\" ]; then", |
77 | " mkdir -p \"$HOME\"", | |
e0c3d906 DD |
78 | "fi", |
79 | "", | |
80 | "export HOME USER", | |
81 | "", | |
82 | "for i in /etc/profile.d/*.sh ; do", | |
83 | " if [ -f $i ]; then", | |
84 | " . $i", | |
85 | " fi", | |
86 | "done", | |
87 | "", | |
bf1d5889 | 88 | "export MAKE_MODE=unix", |
dd3f7f9b DD |
89 | "export PS1='\\[\\033]0;\\w\\007", |
90 | "\\033[32m\\]\\u@\\h \\[\\033[33m\\w\\033[0m\\]", | |
e0c3d906 DD |
91 | "$ '", |
92 | "", | |
40aef45e | 93 | "cd \"$HOME\"", |
e0c3d906 DD |
94 | 0 |
95 | }; | |
96 | ||
3c054baf RC |
97 | #define COMMAND9XARGS String("/E:4096 /c") |
98 | #define COMMAND9XEXE String("\\command.com") | |
904d24fe | 99 | |
3c054baf RC |
100 | static String batname; |
101 | static String iconname; | |
904d24fe | 102 | |
904d24fe | 103 | static void |
3c054baf | 104 | make_link (String const &linkpath, String const &title, String const &target) |
904d24fe | 105 | { |
3c054baf | 106 | String fname = linkpath + "/" + title + ".lnk"; |
904d24fe | 107 | |
3c054baf | 108 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 109 | return; /* already exists */ |
904d24fe | 110 | |
1ac649ed RC |
111 | msg ("make_link %s, %s, %s\n", |
112 | fname.cstr_oneuse(), title.cstr_oneuse(), target.cstr_oneuse()); | |
904d24fe | 113 | |
3c054baf | 114 | io_stream::mkpath_p (PATH_TO_FILE, fname); |
904d24fe | 115 | |
3c054baf | 116 | String exepath; |
904d24fe | 117 | |
3c054baf | 118 | String argbuf; |
904d24fe | 119 | /* If we are running Win9x, build a command line. */ |
904d24fe DD |
120 | if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) |
121 | { | |
3c054baf RC |
122 | exepath = target; |
123 | argbuf = " "; | |
124 | // sprintf (argbuf, " "); | |
904d24fe DD |
125 | } |
126 | else | |
127 | { | |
904d24fe DD |
128 | char windir[MAX_PATH]; |
129 | ||
130 | GetWindowsDirectory (windir, sizeof (windir)); | |
3c054baf RC |
131 | exepath = String(windir) + COMMAND9XEXE; |
132 | argbuf = COMMAND9XARGS + " " + target; | |
133 | // sprintf (argbuf, "%s %s", COMMAND9XARGS, target.cstr_oneuse()); | |
904d24fe DD |
134 | } |
135 | ||
1ac649ed RC |
136 | msg ("make_link_2 (%s, %s, %s, %s)", |
137 | exepath.cstr_oneuse(), argbuf.cstr_oneuse(), | |
138 | iconname.cstr_oneuse(), fname.cstr_oneuse()); | |
139 | make_link_2 (exepath.cstr_oneuse(), argbuf.cstr_oneuse(), | |
140 | iconname.cstr_oneuse(), fname.cstr_oneuse()); | |
904d24fe DD |
141 | } |
142 | ||
143 | static void | |
3c054baf | 144 | start_menu (String const &title, String const &target) |
904d24fe | 145 | { |
904d24fe | 146 | LPITEMIDLIST id; |
24e259bb | 147 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; |
b24c88b3 RC |
148 | SHGetSpecialFolderLocation (NULL, |
149 | issystem ? CSIDL_COMMON_PROGRAMS : | |
150 | CSIDL_PROGRAMS, &id); | |
3c054baf RC |
151 | char _path[_MAX_PATH]; |
152 | SHGetPathFromIDList (id, _path); | |
153 | String path(_path); | |
154 | // Win95 does not use common programs unless multiple users for Win95 is enabled | |
155 | msg ("Program directory for program link: %s", path.cstr_oneuse()); | |
156 | if (path.size() == 0) | |
b24c88b3 RC |
157 | { |
158 | SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id); | |
3c054baf RC |
159 | SHGetPathFromIDList (id, _path); |
160 | path = String(_path); | |
1ac649ed RC |
161 | msg ("Program directory for program link changed to: %s", |
162 | path.cstr_oneuse()); | |
b24c88b3 | 163 | } |
50225eae | 164 | // end of Win95 addition |
3c054baf | 165 | path += "/Cygwin"; |
904d24fe DD |
166 | make_link (path, title, target); |
167 | } | |
168 | ||
169 | static void | |
3c054baf | 170 | desktop_icon (String const &title, String const &target) |
904d24fe DD |
171 | { |
172 | char path[_MAX_PATH]; | |
173 | LPITEMIDLIST id; | |
24e259bb | 174 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; |
50225eae | 175 | //SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_DESKTOP : CSIDL_COMMON_DESKTOPDIRECTORY, &id); |
b24c88b3 RC |
176 | SHGetSpecialFolderLocation (NULL, |
177 | issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : | |
178 | CSIDL_DESKTOPDIRECTORY, &id); | |
904d24fe | 179 | SHGetPathFromIDList (id, path); |
50225eae DD |
180 | // following lines added because it appears Win95 does not use common programs |
181 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
182 | msg ("Desktop directory for desktop link: %s", path); |
183 | if (strlen (path) == 0) | |
184 | { | |
185 | SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id); | |
186 | SHGetPathFromIDList (id, path); | |
187 | msg ("Desktop directory for deskop link changed to: %s", path); | |
188 | } | |
50225eae | 189 | // end of Win95 addition |
904d24fe DD |
190 | make_link (path, title, target); |
191 | } | |
192 | ||
193 | static void | |
194 | make_cygwin_bat () | |
195 | { | |
1ac649ed | 196 | batname = backslash (cygpath ("/cygwin.bat")); |
904d24fe DD |
197 | |
198 | /* if the batch file exists, don't overwrite it */ | |
3c054baf | 199 | if (_access (batname.cstr_oneuse(), 0) == 0) |
904d24fe DD |
200 | return; |
201 | ||
3c054baf | 202 | FILE *bat = fopen (batname.cstr_oneuse(), "wt"); |
904d24fe DD |
203 | if (!bat) |
204 | return; | |
205 | ||
206 | fprintf (bat, "@echo off\n\n"); | |
207 | ||
3c054baf | 208 | fprintf (bat, "%.2s\n", get_root_dir ().cstr_oneuse()); |
b24c88b3 | 209 | fprintf (bat, "chdir %s\n\n", |
3c054baf | 210 | backslash (get_root_dir () + "/bin").cstr_oneuse()); |
904d24fe DD |
211 | |
212 | fprintf (bat, "bash --login -i\n"); | |
213 | ||
214 | fclose (bat); | |
904d24fe DD |
215 | } |
216 | ||
e0c3d906 DD |
217 | static void |
218 | make_etc_profile () | |
219 | { | |
1ac649ed | 220 | String fname = cygpath ("/etc/profile"); |
e0c3d906 DD |
221 | |
222 | /* if the file exists, don't overwrite it */ | |
3c054baf | 223 | if (_access (fname.cstr_oneuse(), 0) == 0) |
e0c3d906 DD |
224 | return; |
225 | ||
3a8e3956 DD |
226 | char os; |
227 | switch (verinfo.dwPlatformId) | |
228 | { | |
b24c88b3 RC |
229 | case VER_PLATFORM_WIN32_NT: |
230 | os = 'N'; | |
231 | break; | |
232 | case VER_PLATFORM_WIN32_WINDOWS: | |
233 | if (verinfo.dwMinorVersion == 0) | |
234 | os = '5'; | |
235 | else | |
236 | os = '8'; | |
237 | break; | |
238 | default: | |
239 | os = '?'; | |
240 | break; | |
3a8e3956 DD |
241 | } |
242 | msg ("os is %c", os); | |
243 | ||
3c054baf | 244 | FILE *p = fopen (fname.cstr_oneuse(), "wb"); |
e0c3d906 DD |
245 | if (!p) |
246 | return; | |
247 | ||
b24c88b3 RC |
248 | int i, allow = 1; |
249 | for (i = 0; etc_profile[i]; i++) | |
3a8e3956 DD |
250 | { |
251 | if (etc_profile[i][0] == '@') | |
252 | { | |
253 | allow = 0; | |
254 | msg ("profile: %s", etc_profile[i]); | |
b24c88b3 | 255 | for (const char *cp = etc_profile[i] + 1; *cp; cp++) |
3a8e3956 DD |
256 | if (*cp == os || *cp == '*') |
257 | allow = 1; | |
258 | msg ("allow is %d\n", allow); | |
259 | } | |
260 | else if (allow) | |
261 | fprintf (p, "%s\n", etc_profile[i]); | |
262 | } | |
263 | ||
264 | fclose (p); | |
265 | } | |
266 | ||
f57c332f | 267 | static int |
b24c88b3 | 268 | uexists (const char *path) |
f57c332f | 269 | { |
1ac649ed | 270 | String f = cygpath (path); |
3c054baf | 271 | int a = _access (f.cstr_oneuse(), 0); |
f57c332f DD |
272 | if (a == 0) |
273 | return 1; | |
274 | return 0; | |
275 | } | |
276 | ||
3a8e3956 | 277 | static void |
f57c332f | 278 | make_passwd_group () |
3a8e3956 | 279 | { |
1ac649ed | 280 | String fname = cygpath ("/etc/postinstall/passwd-grp.bat"); |
3c054baf | 281 | io_stream::mkpath_p (PATH_TO_FILE, fname); |
31324d15 | 282 | |
bb087dce | 283 | if (uexists ("/etc/passwd") && uexists ("/etc/group")) |
31324d15 | 284 | return; |
bb087dce | 285 | |
3a8e3956 | 286 | if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) |
ef2007fd | 287 | { |
bb849dbd | 288 | packagedb db; |
cbfc4215 | 289 | packagemeta *pkg = db.packages.getbykey ("cygwin"); |
bb849dbd | 290 | if (pkg && pkg->installed) |
ef2007fd | 291 | { |
c46a33a9 | 292 | /* mkpasswd and mkgroup are not working on 9x/ME up to 1.1.5-4 */ |
3c054baf RC |
293 | String border_version = canonicalize_version ("1.1.5-4"); |
294 | String inst_version = | |
bb849dbd | 295 | canonicalize_version (pkg->installed->Canonical_version ()); |
3c054baf | 296 | if (inst_version.compare(border_version) <= 0) |
bb087dce | 297 | return; |
ef2007fd CV |
298 | } |
299 | } | |
3a8e3956 | 300 | |
bb087dce RC |
301 | FILE *p = fopen (fname.cstr_oneuse(), "wt"); |
302 | if (!p) | |
303 | return; | |
f57c332f DD |
304 | if (!uexists ("/etc/passwd")) |
305 | fprintf (p, "bin\\mkpasswd -l > etc\\passwd\n"); | |
306 | if (!uexists ("/etc/group")) | |
307 | fprintf (p, "bin\\mkgroup -l > etc\\group\n"); | |
e0c3d906 DD |
308 | fclose (p); |
309 | } | |
310 | ||
904d24fe DD |
311 | static void |
312 | save_icon () | |
313 | { | |
1ac649ed | 314 | iconname = backslash (cygpath ("/cygwin.ico")); |
904d24fe DD |
315 | |
316 | HRSRC rsrc = FindResource (NULL, "CYGWIN.ICON", "FILE"); | |
317 | if (rsrc == NULL) | |
318 | { | |
319 | fatal ("FindResource failed"); | |
320 | } | |
321 | HGLOBAL res = LoadResource (NULL, rsrc); | |
322 | char *data = (char *) LockResource (res); | |
323 | int len = SizeofResource (NULL, rsrc); | |
324 | ||
3c054baf | 325 | FILE *f = fopen (iconname.cstr_oneuse(), "wb"); |
904d24fe DD |
326 | if (f) |
327 | { | |
328 | fwrite (data, 1, len, f); | |
329 | fclose (f); | |
330 | } | |
331 | } | |
332 | ||
50225eae | 333 | static void |
b24c88b3 | 334 | do_desktop_setup () |
50225eae DD |
335 | { |
336 | save_icon (); | |
337 | ||
338 | make_cygwin_bat (); | |
339 | make_etc_profile (); | |
340 | make_passwd_group (); | |
341 | ||
b24c88b3 RC |
342 | if (root_menu) |
343 | { | |
344 | start_menu ("Cygwin Bash Shell", batname); | |
345 | } | |
50225eae | 346 | |
b24c88b3 RC |
347 | if (root_desktop) |
348 | { | |
349 | desktop_icon ("Cygwin", batname); | |
350 | } | |
50225eae DD |
351 | } |
352 | ||
353 | static int da[] = { IDC_ROOT_DESKTOP, 0 }; | |
354 | static int ma[] = { IDC_ROOT_MENU, 0 }; | |
355 | ||
356 | static void | |
357 | check_if_enable_next (HWND h) | |
358 | { | |
359 | EnableWindow (GetDlgItem (h, IDOK), 1); | |
360 | } | |
361 | ||
362 | static void | |
363 | load_dialog (HWND h) | |
364 | { | |
365 | rbset (h, da, root_desktop); | |
366 | rbset (h, ma, root_menu); | |
367 | check_if_enable_next (h); | |
368 | } | |
369 | ||
b24c88b3 | 370 | static int |
3c054baf | 371 | check_desktop (String const title, String const target) |
50225eae DD |
372 | { |
373 | char path[_MAX_PATH]; | |
374 | LPITEMIDLIST id; | |
375 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; | |
b24c88b3 RC |
376 | SHGetSpecialFolderLocation (NULL, |
377 | issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : | |
378 | CSIDL_DESKTOPDIRECTORY, &id); | |
50225eae DD |
379 | SHGetPathFromIDList (id, path); |
380 | // following lines added because it appears Win95 does not use common programs | |
381 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
382 | msg ("Desktop directory for desktop link: %s", path); |
383 | if (strlen (path) == 0) | |
384 | { | |
385 | SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id); | |
386 | SHGetPathFromIDList (id, path); | |
387 | msg ("Desktop directory for deskop link changed to: %s", path); | |
388 | } | |
50225eae | 389 | // end of Win95 addition |
1ac649ed | 390 | String fname = String (path) + "/" + title + ".lnk"; |
50225eae | 391 | |
3c054baf | 392 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 393 | return 0; /* already exists */ |
42bf5b92 | 394 | |
1ac649ed | 395 | fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */ |
42bf5b92 | 396 | |
3c054baf | 397 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 398 | return 0; /* already exists */ |
50225eae DD |
399 | |
400 | return IDC_ROOT_DESKTOP; | |
401 | } | |
402 | ||
b24c88b3 | 403 | static int |
3c054baf | 404 | check_startmenu (String const title, String const target) |
50225eae DD |
405 | { |
406 | char path[_MAX_PATH]; | |
407 | LPITEMIDLIST id; | |
408 | int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0; | |
b24c88b3 RC |
409 | SHGetSpecialFolderLocation (NULL, |
410 | issystem ? CSIDL_COMMON_PROGRAMS : | |
411 | CSIDL_PROGRAMS, &id); | |
50225eae DD |
412 | SHGetPathFromIDList (id, path); |
413 | // following lines added because it appears Win95 does not use common programs | |
414 | // unless it comes into play when multiple users for Win95 is enabled | |
b24c88b3 RC |
415 | msg ("Program directory for program link: %s", path); |
416 | if (strlen (path) == 0) | |
417 | { | |
418 | SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id); | |
419 | SHGetPathFromIDList (id, path); | |
420 | msg ("Program directory for program link changed to: %s", path); | |
421 | } | |
50225eae | 422 | // end of Win95 addition |
398dd7b2 | 423 | strcat (path, "/Cygwin"); |
1ac649ed | 424 | String fname = String (path) + "/" + title + ".lnk"; |
50225eae | 425 | |
3c054baf | 426 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 427 | return 0; /* already exists */ |
42bf5b92 | 428 | |
1ac649ed | 429 | fname = String (path) + "/" + title + ".pif"; /* check for a pif as well */ |
42bf5b92 | 430 | |
3c054baf | 431 | if (_access (fname.cstr_oneuse(), 0) == 0) |
b24c88b3 | 432 | return 0; /* already exists */ |
42bf5b92 | 433 | |
50225eae DD |
434 | return IDC_ROOT_MENU; |
435 | } | |
436 | ||
437 | static void | |
438 | save_dialog (HWND h) | |
439 | { | |
b24c88b3 | 440 | root_desktop = rbget (h, da); |
50225eae DD |
441 | root_menu = rbget (h, ma); |
442 | } | |
443 | ||
444 | static BOOL | |
445 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
446 | { | |
447 | switch (id) | |
448 | { | |
449 | ||
450 | case IDC_ROOT_DESKTOP: | |
451 | case IDC_ROOT_MENU: | |
452 | save_dialog (h); | |
453 | check_if_enable_next (h); | |
454 | break; | |
50225eae | 455 | } |
b24c88b3 | 456 | return 0; |
50225eae DD |
457 | } |
458 | ||
ab57ceaa RC |
459 | bool |
460 | DesktopSetupPage::Create () | |
50225eae | 461 | { |
ab57ceaa | 462 | return PropertyPage::Create (NULL, dialog_cmd, IDD_DESKTOP); |
50225eae DD |
463 | } |
464 | ||
904d24fe | 465 | void |
ab57ceaa | 466 | DesktopSetupPage::OnInit () |
904d24fe | 467 | { |
ab57ceaa | 468 | // FIXME: This CoInitialize() feels like it could be moved to startup in main.cc. |
904d24fe | 469 | CoInitialize (NULL); |
3a8e3956 DD |
470 | verinfo.dwOSVersionInfoSize = sizeof (verinfo); |
471 | GetVersionEx (&verinfo); | |
b24c88b3 | 472 | root_desktop = |
1ac649ed | 473 | check_desktop ("Cygwin", backslash (cygpath ("/cygwin.bat"))); |
b24c88b3 RC |
474 | root_menu = |
475 | check_startmenu ("Cygwin Bash Shell", | |
1ac649ed | 476 | backslash (cygpath ("/cygwin.bat"))); |
ab57ceaa RC |
477 | load_dialog (GetHWND ()); |
478 | } | |
42bf5b92 | 479 | |
ab57ceaa RC |
480 | long |
481 | DesktopSetupPage::OnBack () | |
482 | { | |
483 | HWND h = GetHWND (); | |
484 | save_dialog (h); | |
485 | NEXT (IDD_CHOOSE); | |
486 | return IDD_CHOOSER; | |
487 | } | |
488 | ||
489 | bool | |
490 | DesktopSetupPage::OnFinish () | |
491 | { | |
492 | HWND h = GetHWND (); | |
493 | save_dialog (h); | |
494 | do_desktop_setup (); | |
495 | NEXT (IDD_S_POSTINSTALL); | |
496 | do_postinstall (GetInstance (), h); | |
904d24fe | 497 | |
ab57ceaa | 498 | return true; |
904d24fe | 499 | } |