]> cygwin.com Git - cygwin-apps/setup.git/blobdiff - main.cc
2003-02-16 Pavel Tsekov <ptsekov@gmx.net>
[cygwin-apps/setup.git] / main.cc
diff --git a/main.cc b/main.cc
index ac1cfba893c774b0d127505cee7850bf5cf49837..cb6a8c7146d3bd74ec7019416be118116648eafa 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -1,4 +1,4 @@
-/*
+ /*
  * Copyright (c) 2000, Red Hat, Inc.
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@ static const char *cvsid =
 #include "msg.h"
 #include "find.h"
 #include "mount.h"
-#include "log.h"
+#include "LogFile.h"
 #include "version.h"
 
 #include "port.h"
@@ -48,6 +48,7 @@ static const char *cvsid =
 
 // Page class headers
 #include "splash.h"
+#include "AntiVirus.h"
 #include "source.h"
 #include "root.h"
 #include "localdir.h"
@@ -57,11 +58,15 @@ static const char *cvsid =
 #include "threebar.h"
 #include "desktop.h"
 
+#include "getopt++/GetOption.h"
+#include "getopt++/BoolOption.h"
+
 int next_dialog;
-int exit_msg = 0;
 
 HINSTANCE hinstance;
 
+static BoolOption UnattendedOption (false, 'q', "quiet-mode", "Unattended setup mode");
+
 /* Maximum size of a SID on NT/W2K. */
 #define MAX_SID_LEN    40
 
@@ -73,13 +78,15 @@ HINSTANCE hinstance;
 #define iswinnt                (GetVersion() < 0x80000000)
 
 void
-set_default_dacl ()
+set_default_sec ()
 {
   /* To assure that the created files have a useful ACL, the 
      default DACL in the process token is set to full access to
      everyone. This applies to files and subdirectories created
      in directories which don't propagate permissions to child
-     objects. */
+     objects. 
+     To assure that the files group is meaningful, a token primary
+     group of None is changed to Users or Administrators. */
 
   /* Create a buffer which has enough room to contain the TOKEN_DEFAULT_DACL
      structure plus an ACL with one ACE. */
@@ -92,65 +99,205 @@ set_default_dacl ()
   /* Initialize the ACL for containing one ACE. */
   if (!InitializeAcl (dacl->DefaultDacl, TOKEN_ACL_SIZE (1), ACL_REVISION))
     {
-      log (LOG_TIMESTAMP, "InitializeAcl() failed: %lu", GetLastError ());
+      log (LOG_TIMESTAMP) << "InitializeAcl() failed: " << GetLastError ()
+       << endLog;
       return;
     }
 
-  /* Get the SID for "Everyone". */
-  PSID sid;
+  PSID esid = NULL, asid = NULL, usid = NULL;
+  HANDLE token = NULL;
+  struct {
+    PSID psid;
+    char buf[MAX_SID_LEN];
+  } gsid;
+  char lsid[MAX_SID_LEN];
+  char compname[MAX_COMPUTERNAME_LENGTH + 1];
+  char domain[MAX_COMPUTERNAME_LENGTH + 1];
+  DWORD size;
+
   SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_WORLD_SID_AUTHORITY };
-  if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &sid))
+  if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &esid))
     {
-      log (LOG_TIMESTAMP, "AllocateAndInitializeSid() failed: %lu",
-          GetLastError ());
-      return;
+      log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
+          GetLastError () << endLog;
+      goto out;
     }
 
   /* Create the ACE which grants full access to "Everyone" and store it
      in dacl->DefaultDacl. */
   if (!AddAccessAllowedAce
-      (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, sid))
+      (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, esid))
     {
-      log (LOG_TIMESTAMP, "AddAccessAllowedAce() failed: %lu",
-          GetLastError ());
+      log (LOG_TIMESTAMP) << "AddAccessAllowedAce() failed: %lu" << 
+          GetLastError () << endLog;
       goto out;
     }
 
   /* Get the processes access token. */
-  HANDLE token;
   if (!OpenProcessToken (GetCurrentProcess (),
                         TOKEN_READ | TOKEN_ADJUST_DEFAULT, &token))
     {
-      log (LOG_TIMESTAMP, "OpenProcessToken() failed: %lu", GetLastError ());
+      log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " << 
+       GetLastError () << endLog;
       goto out;
     }
 
   /* Set the default DACL to the above computed ACL. */
   if (!SetTokenInformation (token, TokenDefaultDacl, dacl, sizeof buf))
-    log (LOG_TIMESTAMP, "OpenProcessToken() failed: %lu", GetLastError ());
+    log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " << 
+      GetLastError () << endLog;
 
-  /* Close token handle. */
-  CloseHandle (token);
 
-out:
-  /* Free memory occupied by the "Everyone" SID. */
-  FreeSid (sid);
+  /* Get the default group */
+  if (!GetTokenInformation (token, TokenPrimaryGroup, &gsid, sizeof gsid, &size))
+    {
+      log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " << 
+       GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Get the computer name */
+  if (!GetComputerName (compname, (size = sizeof compname, &size)))
+    {
+      log (LOG_TIMESTAMP) << "GetComputerName() failed: " << 
+       GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Get the local domain SID */
+  SID_NAME_USE use;
+  DWORD sz;
+  if (!LookupAccountName (NULL, compname, lsid, (size = sizeof lsid, &size), 
+                         domain, (sz = sizeof domain, &sz), &use)) 
+    {
+      log (LOG_TIMESTAMP) << "LookupAccountName() failed: " << 
+       GetLastError () << endLog;
+      goto out;
+    }
+
+  /* Create the None SID from the domain SID.
+     On NT the last subauthority of a domain is -1 and it is replaced by the RID.
+     On other systems the RID is appended. */
+  sz = *GetSidSubAuthorityCount (lsid);
+  if (*GetSidSubAuthority (lsid, sz -1) != (DWORD) -1) 
+    *GetSidSubAuthorityCount (lsid) = ++sz;
+  *GetSidSubAuthority (lsid, sz -1) = DOMAIN_GROUP_RID_USERS;
+  
+  /* See if the group is None */
+  if (EqualSid (gsid.psid, lsid))
+    {
+      bool isadmins = false, isusers = false;
+      sid_auth = (SID_IDENTIFIER_AUTHORITY) { SECURITY_NT_AUTHORITY };
+      /* Get the SID for "Administrators" S-1-5-32-544 */
+      if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, 
+                                    DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &asid))
+        {
+         log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
+           GetLastError () << endLog;
+         goto out;
+       }
+      /* Get the SID for "Users" S-1-5-32-545 */
+      if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, 
+                                    DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &usid))
+        {
+         log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
+           GetLastError () << endLog;
+         goto out;
+       }
+      /* Get the token groups */
+      if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size)
+         && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+        {
+         log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
+           GetLastError () << endLog;
+         goto out;
+       }
+      else 
+        {
+         char buf[size];
+         TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf;
+
+         if (!GetTokenInformation (token, TokenGroups, buf, size, &size))
+           {
+             log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
+               GetLastError () << endLog;
+             goto out;
+           }
+         else
+           /* See if admins or users is present */
+           for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+             {
+               isadmins = isadmins || EqualSid(groups->Groups[pg].Sid, asid);
+               isusers = isusers || EqualSid(groups->Groups[pg].Sid, usid);
+             }
+       }
+      /* Set the default group to one of the above computed SID. */
+      PSID nsid = NULL;
+      if (isusers)
+      {
+       nsid = usid;
+       log(LOG_TIMESTAMP) << "Changing gid to Users" << endLog;
+      }
+      else if (isadmins)
+      {
+       nsid = asid;
+       log(LOG_TIMESTAMP) << "Changing gid to Administrators" << endLog;
+      }
+      if (nsid && !SetTokenInformation (token, TokenPrimaryGroup, &nsid, sizeof nsid))
+       log (LOG_TIMESTAMP) << "SetTokenInformation() failed: " << 
+         GetLastError () << endLog;
+    }
+ out:
+  /* Close token handle. */
+  if (token)
+    CloseHandle (token);
+  
+  /* Free memory occupied by the SIDs. */
+  if (esid)
+    FreeSid (esid);
+  if (asid)
+    FreeSid (asid);
+  if (usid)
+    FreeSid (usid);
 }
 
 // Other threads talk to this page, so we need to have it externable.
 ThreeBarProgressPage Progress;
 
+// This is a little ugly, but the decision about where to log occurs
+// after the source is set AND the root mount obtained
+// so we make the actual logger available to the appropriate routine(s).
+LogFile *theLog;
+
+#ifndef __CYGWIN__
 int WINAPI
 WinMain (HINSTANCE h,
         HINSTANCE hPrevInstance, LPSTR command_line, int cmd_show)
 {
+
   hinstance = h;
+#else
+int
+main (int argc, char **argv)
+{
+  hinstance = GetModuleHandle (NULL);
+#endif
+
+  char *cwd=new char[_MAX_PATH];
+  GetCurrentDirectory (_MAX_PATH, cwd);
+  local_dir = String (cwd);
+  delete cwd;
+
+  LogSingleton::SetInstance (*(theLog = LogFile::createLogFile()));
+  theLog->setFile (LOG_BABBLE, local_dir + "/setup.log.full", false);
+  theLog->setFile (0, local_dir + "/setup.log", true);
 
   next_dialog = IDD_SPLASH;
 
-  log (LOG_TIMESTAMP, "Starting cygwin install, version %s", version);
+  log (LOG_PLAIN) << "Starting cygwin install, version " << version << endLog;
 
   SplashPage Splash;
+  AntiVirusPage AntiVirus;
   SourcePage Source;
   RootPage Root;
   LocalDirPage LocalDir;
@@ -160,33 +307,44 @@ WinMain (HINSTANCE h,
   DesktopSetupPage Desktop;
   PropSheet MainWindow;
 
-  char cwd[_MAX_PATH];
-  GetCurrentDirectory (sizeof (cwd), cwd);
-  local_dir = new char [strlen (cwd) + 1];
-  local_dir [strlen (cwd)] = '\0';
-  strcpy (local_dir, cwd);
-  log (0, "Current Directory: %s", cwd);
+  log (LOG_TIMESTAMP) << "Current Directory: " << local_dir << endLog;
 
-  char **argv;
+  // TODO: make an equivalent for __argv under cygwin.
+  char **_argv;
+#ifndef __CYGWIN__
   int argc;
-  log (LOG_TIMESTAMP, "Command line parameters\n");
-  for (argc = 0, argv = __argv; *argv; argv++)
-    log (LOG_TIMESTAMP, "%d - '%s'\n", argc++, *argv);
-  log (LOG_TIMESTAMP, "%d parameters passed\n", argc);
+//  char **_argv;
+#ifndef __CYGWIN__
+  for (argc = 0, _argv = __argv; *_argv; _argv++)++argc;
+  _argv = __argv;
+#else
+//  for (argc = 0, _argv = argv; *_argv; _argv++)++argc;
+  _argv = argv;
+#endif
+#else
+  _argv = argv;
+#endif
+
+  if (!GetOption::GetInstance().Process (argc,_argv))
+    theLog->exit(1);
+// #endif
+
+  unattended_mode = UnattendedOption;
 
-  /* Set the default DACL only on NT/W2K. 9x/ME has no idea of access
-     control lists and security at all. */
+  /* Set the default DACL and Group only on NT/W2K. 9x/ME has 
+     no idea of access control lists and security at all. */
   if (iswinnt)
-    set_default_dacl ();
+    set_default_sec ();
 
   // Initialize common controls
   InitCommonControls ();
 
   // Init window class lib
-  Window::SetAppInstance (h);
+  Window::SetAppInstance (hinstance);
 
   // Create pages
   Splash.Create ();
+  AntiVirus.Create ();
   Source.Create ();
   Root.Create ();
   LocalDir.Create ();
@@ -198,6 +356,7 @@ WinMain (HINSTANCE h,
 
   // Add pages to sheet
   MainWindow.AddPage (&Splash);
+  MainWindow.AddPage (&AntiVirus);
   MainWindow.AddPage (&Source);
   MainWindow.AddPage (&Root);
   MainWindow.AddPage (&LocalDir);
@@ -210,7 +369,7 @@ WinMain (HINSTANCE h,
   // Create the PropSheet main window
   MainWindow.Create ();
 
-  exit_setup (0);
+  theLog->exit (0);
   /* Keep gcc happy :} */
   return 0;
 }
This page took 0.032798 seconds and 5 git commands to generate.