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