archive.extracted: fix problems with overwrite arg
archive.extracted: fix problems with overwrite arg

Pull request #37889 introduced several problems:

1. It forces a wipe of the extracted contents if you are setting
   ``overwrite`` to ``True``. This should be configurable, to allow for
   the use case where extraction should be forced but there are contents
   added to the extracted content which the user does not want purged
   before the archive is re-extracted.

2. It ignores the case where ``enforce_toplevel`` is set to ``False``
   and the archive doesn't have all contents in a single top-level
   directory, by only deleting the first listed top-level directory (and
   ignoring completely any top-level files).

3. It ignores the case where ``archive.list`` was unable to list the
   contents of the archive (in which case ``contents`` would be
   ``None``). This would result in a TypeError when this case was
   combined with setting ``overwrite`` to ``True``.

This commit fixes all of the above problems. Additionally, a new
argument called ``clean`` now controls whether destination paths are
wiped before extraction is performed.

Finally, an issue with how I implemented detection (and cleaning) of
paths with incorrect types has been fixed. Specifically, when a path
that should have been a directory is instead a file, the ``os.stat()``
will raise an ENOTDIR when the path passed to it contains a trailing
path separator, because the path exists but is not a directory.

saltstack/salt,saltstack/salt,saltstack/salt,saltstack/salt,saltstack/salt