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