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