public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Houder <houder@xs4all.nl>
To: cygwin@cygwin.com
Subject: Setup.exe: solution to misbehaviour
Date: Tue, 16 Apr 2019 07:19:00 -0000	[thread overview]
Message-ID: <550c60bc7704a5955804e38504cbc4f1@xs4all.nl> (raw)

[-- Attachment #1: Type: text/plain, Size: 1706 bytes --]

L.S.,

Setup.exe writes "user defaults" to /etc/setup/setup.rc in the root
directory. Among these user defaults (which should override program
defaults) are "last-action" and "last-cache".

last-cache is an alias for the Local Package Directory (abbreviated
to local directory), the directory where the tarballs (or packages)
will be stored.

When setup.exe starts, one has to choose between "Download to local
directory", "Install fr. local directory" or "Download end Install".

As a reminder, setup.exe will show you the "last-action", i.e. what
action was chosen by you when you last invoked setup.exe.

However "all of the above" is in vain, if setup.exe fails to select
the correct root directory.

Currently, setup.exe fails to honour the -R option, which one uses
to specify a different location for the root directory.

setup.exe also fails to look for /etc/setup/setup.rc in the current
directory when setup.exe is started from the root directory.

I have written about this misbehaviour of setup.exe here:

     https://cygwin.com/ml/cygwin/2019-04/msg00032.html
     ( Setup: why consult registry (rootdir) if -R has been specified? )

Attached (I hope) to this post you will find a corrected version of
the UserSettings::open_settings() method; it determines the location
of the root directory as follows:

  - read /etc/setup/setup.rc from the specified root directory (-R)
    and if file exists
   - insert root directory in mount_table
  - else read /etc/setup/setup.rc from the current directory and if
    file exist
   - insert root directory in mount_table
  - else fall back to the whacky default (rootdir from registry)
    (root directory inserted in mount_table)

Good luck.

Henri

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: open_settings.txt --]
[-- Type: text/x-c; name=open_settings.txt, Size: 5896 bytes --]

...

// Henri: required
#include "mount.h" // set_root_dir()
#include "getopt++/StringOption.h" // RootOption
extern StringOption RootOption;

...

// Henri: original function replaced by this one (more clear than modifying the existing function)
#if 1
io_stream *
UserSettings::open_settings (const char *filename, std::string &pathname)
{
/*
  Obtain user settings (last-action, last-cache -- aka local directory, last-mirror etc.) from /etc/setup/setup.rc
   - at startup (setup.exe), the root directory may have been specified explicitly (-R) or it may have been specified
     implicitly by starting setup.exe from the root directory, or its value may be present in registry ("rootdir")
   - if all options fail, it will default to either X:\Cygwin64 or X:\Cygwin (where X is the system drive)
   Note:
   - although the value of the root directory can be overruled in the Root Page later on, /etc/setup/setup.rc is read
     at startup from the root directory as explained above
   - however, said value can NOT be overruled in case of "Download to Local directory"
   Algorithm:
   - read /etc/setup/setup.rc from the specified root directory (-R) and if file exists
    - note: the root directory is NOT the Unix root; it is the Windows directory where the Cygwin packages
      have been, or will be installed
   - else read /etc/setup/setup.rc from the current directory and if file exists
    - this makes only sense if the current directory equals the root directory (i.e. this is the directory where
      the file /etc/setup/setup.rc will be written!)
   - else fall back to the whacky default (rootdir from registry)
 */
  io_stream *f = NULL; // Henri
  bool found = false; // Henri

  // Henri: take root directory seriously if explicitly specified (-R) ! ... setup mount_table (mount.cc)
  std::string my_RD;
  if (std::string (RootOption).size ()) {
    my_RD = std::string (RootOption);
    //LogPlainPrintf("UserSettings::open_settings: my_RD = %s\n", my_RD.c_str() );
    pathname = "file://" + my_RD + "/etc/setup/" + filename;
    f = io_stream::open(pathname, "rt", 0);
    //LogPlainPrintf("UserSettings::open_settings: 1. pathname = %s\n", pathname.c_str() );
    if (f) {
        found = true;
        set_root_dir(my_RD); // required in case of download
    }
  }

  // Henri: current directory (should!) equals the root directory ... setup mount_table
  // Henri: this is specifying the root directory implicitly ...
  if (found == false) {
  // Henri:  original code + correction (basically a daft option)
    pathname = "file://";
    pathname += cwd;
    if (!isdirsep (cwd[cwd.size () - 1]) && !isdirsep (filename[0]))
        pathname += "/";
    pathname += "etc/setup/"; // Henri: heck! "etc/setup/" was missing in pathname ...
    pathname += filename;
    //LogPlainPrintf("UserSettings::open_settings: 2. pathname = %s\n", pathname.c_str() );
    f = io_stream::open(pathname, "rt", 0);
    if (f) {
        found = true;
        set_root_dir(cwd); // required in case of download
    }
  }
  
  if (!f) // found == false
    {
      pathname = "cygfile:///etc/setup/";
      pathname += filename;
      //LogPlainPrintf(" *** WARNING *** UserSettings::open_settings: 3. pathname = %s\n", pathname.c_str() );
#if 0
      LogPlainPrintf(" *** WARNING ***\n");
      LogPlainPrintf("     rootdir from registry will be used as the root directory. Defaults will be\n");
      LogPlainPrintf("     obtained from /etc/setup/setup.rc over there.\n");
      LogPlainPrintf("     Defaults will also be written over there, unless another root directory is\n");
      LogPlainPrintf("     chosen later on (Not possible in case of Download to Local Directory).\n");
      LogPlainPrintf(" END WARNING\n");
#endif
      f = io_stream::open (pathname, "rt", 0); // Henri: creates mount_table where / maps to rootdir from registry
    }
  //if (!f) pathname = ""; // Henri: dont lie! (however, lying is prerequisite to keep setup.exe working)
  /*
   - ignore error if file does not exist ...
   - an exception occured if the file did not exist ... however, a non-existing mount-point was fine ... Hark!
    - a null pointer is returned if the file does not exist, while a (valid) pointer is returned in case of a
      non-existing mount-point ...
   - this software is garbage
   */

  return f;
}
#endif // Henri: end replace open_settings

#if 0 // Henri: put out the garbage ...
io_stream *
UserSettings::open_settings (const char *filename, std::string &pathname)
{
  pathname = "file://";
  pathname += cwd;
  if (!isdirsep (cwd[cwd.size () - 1]) && !isdirsep (filename[0]))
    pathname += "/"; // Henri: WRONG: missing "etc/setup/" in pathname!
  pathname += filename;
  io_stream *f = io_stream::open(pathname, "rt", 0);
  if (!f)
    {
      pathname = "cygfile:///etc/setup/";
      pathname += filename;
      f = io_stream::open (pathname, "rt", 0);
    }
  return f; // Henri: no reset of pathname if a null pointer is returned
            // Henri: Oh hell, a (valid) pointer is returned in case of a NON-existing mount-point ...
}
#endif

// Henri: relevance of cwd? As local directory: None! As root directory, only if the current directory equals the root directory
// Henri: why? /etc/setup/setup.rc is eventually written out to /etc/setup/setup.rc in the root directory; by definition the root
// Henri: can be equal to the current directory (start directory of setup.exe), but it does not require that!
// Henri: it is a daft option! And only useful if one wants to escape the dictation by registry.
UserSettings::UserSettings (std::string local_dir) // Henri: basically the start directory (cwd) of setup.exe is provided here
  : table (NULL), table_len (-1), cwd (local_dir)
{
  global = this;
  extend_table (0);
  io_stream *f = open_settings ("setup.rc", filename); // Henri: Jezus C.! This initializes the member variable ... Tada!
...

=====

[-- Attachment #3: Type: text/plain, Size: 219 bytes --]


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

             reply	other threads:[~2019-04-16  7:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-16  7:19 Houder [this message]
2019-04-16  9:09 ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=550c60bc7704a5955804e38504cbc4f1@xs4all.nl \
    --to=houder@xs4all.nl \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).