Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package minio-client for openSUSE:Factory 
checked in at 2023-10-16 23:01:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/minio-client (Old)
 and      /work/SRC/openSUSE:Factory/.minio-client.new.20540 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "minio-client"

Mon Oct 16 23:01:24 2023 rev:50 rq:1118013 version:20231014T015703Z

Changes:
--------
--- /work/SRC/openSUSE:Factory/minio-client/minio-client.changes        
2023-10-10 20:59:05.223442759 +0200
+++ /work/SRC/openSUSE:Factory/.minio-client.new.20540/minio-client.changes     
2023-10-16 23:01:27.730005074 +0200
@@ -1,0 +2,12 @@
+Sat Oct 14 18:52:28 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 20231014T015703Z:
+  * prom: Allow insecure TLS connections if --insecure is provided
+    (#4716)
+  * Bump golang.org/x/net from 0.15.0 to 0.17.0 (#4713)
+  * Validation optimization - reduce HEAD calls during cp and mv
+    operations (#4710)
+  * Use the new golang version 1.21.3 (#4714)
+  * Add --stats to traces (#4669)
+
+-------------------------------------------------------------------

Old:
----
  mc-20231004T065256Z.obscpio

New:
----
  mc-20231014T015703Z.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ minio-client.spec ++++++
--- /var/tmp/diff_new_pack.TpbW7H/_old  2023-10-16 23:01:28.666038875 +0200
+++ /var/tmp/diff_new_pack.TpbW7H/_new  2023-10-16 23:01:28.666038875 +0200
@@ -22,7 +22,7 @@
 %define binary_name minio-client
 
 Name:           minio-client
-Version:        20231004T065256Z
+Version:        20231014T015703Z
 Release:        0
 Summary:        Client for MinIO
 License:        AGPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.TpbW7H/_old  2023-10-16 23:01:28.702040175 +0200
+++ /var/tmp/diff_new_pack.TpbW7H/_new  2023-10-16 23:01:28.706040319 +0200
@@ -5,7 +5,7 @@
     <param name="exclude">.git</param>
     <param name="changesgenerate">enable</param>
     <param name="versionformat">@PARENT_TAG@</param>
-    <param name="revision">RELEASE.2023-10-04T06-52-56Z</param>
+    <param name="revision">RELEASE.2023-10-14T01-57-03Z</param>
     <param name="match-tag">RELEASE.*</param>
     <param 
name="versionrewrite-pattern">RELEASE\.(.*)-(.*)-(.*)-(.*)-(.*)</param>
     <param name="versionrewrite-replacement">\1\2\3\4\5</param>
@@ -19,7 +19,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="manual">
-    <param name="archive">mc-20231004T065256Z.obscpio</param>
+    <param name="archive">mc-20231014T015703Z.obscpio</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.TpbW7H/_old  2023-10-16 23:01:28.726041042 +0200
+++ /var/tmp/diff_new_pack.TpbW7H/_new  2023-10-16 23:01:28.730041186 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/minio/mc</param>
-              <param 
name="changesrevision">eca8310ac822cf0e533c6bd3fb85c8d6099d1465</param></service></servicedata>
+              <param 
name="changesrevision">d158b9a478a6a5a74795f01097d069be82edfff6</param></service></servicedata>
 (No newline at EOF)
 

++++++ mc-20231004T065256Z.obscpio -> mc-20231014T015703Z.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/.github/workflows/vulncheck.yml 
new/mc-20231014T015703Z/.github/workflows/vulncheck.yml
--- old/mc-20231004T065256Z/.github/workflows/vulncheck.yml     2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/.github/workflows/vulncheck.yml     2023-10-14 
03:57:03.000000000 +0200
@@ -16,7 +16,7 @@
     - name: Set up Go
       uses: actions/setup-go@v3
       with:
-        go-version: 1.21.1
+        go-version: 1.21.3
         check-latest: true
     - name: Get official govulncheck
       run: go install golang.org/x/vuln/cmd/govulncheck@latest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/admin-scanner-status.go 
new/mc-20231014T015703Z/cmd/admin-scanner-status.go
--- old/mc-20231004T065256Z/cmd/admin-scanner-status.go 2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/cmd/admin-scanner-status.go 2023-10-14 
03:57:03.000000000 +0200
@@ -208,11 +208,13 @@
                        return m, tea.Quit
                }
                return m, nil
+       case spinner.TickMsg:
+               var cmd tea.Cmd
+               m.spinner, cmd = m.spinner.Update(msg)
+               return m, cmd
        }
 
-       var cmd tea.Cmd
-       m.spinner, cmd = m.spinner.Update(msg)
-       return m, cmd
+       return m, nil
 }
 
 func (m *scannerMetricsUI) View() string {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/admin-scanner-trace.go 
new/mc-20231014T015703Z/cmd/admin-scanner-trace.go
--- old/mc-20231004T065256Z/cmd/admin-scanner-trace.go  2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/cmd/admin-scanner-trace.go  2023-10-14 
03:57:03.000000000 +0200
@@ -169,7 +169,7 @@
                if traceInfo.Err != nil {
                        fatalIf(probe.NewError(traceInfo.Err), "Unable to 
listen to http trace")
                }
-               if matchTrace(mopts, traceInfo) {
+               if mopts.matches(traceInfo) {
                        printTrace(verbose, traceInfo)
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/admin-trace.go 
new/mc-20231014T015703Z/cmd/admin-trace.go
--- old/mc-20231004T065256Z/cmd/admin-trace.go  2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/admin-trace.go  2023-10-14 03:57:03.000000000 
+0200
@@ -27,8 +27,12 @@
        "path"
        "sort"
        "strings"
+       "sync"
        "time"
 
+       "github.com/charmbracelet/bubbles/spinner"
+       tea "github.com/charmbracelet/bubbletea"
+       "github.com/charmbracelet/lipgloss"
        "github.com/dustin/go-humanize"
        "github.com/fatih/color"
        "github.com/minio/cli"
@@ -36,6 +40,7 @@
        "github.com/minio/madmin-go/v3"
        "github.com/minio/mc/pkg/probe"
        "github.com/minio/pkg/v2/console"
+       "github.com/olekukonko/tablewriter"
 )
 
 var adminTraceFlags = []cli.Flag{
@@ -84,6 +89,16 @@
                Usage: "trace only failed requests",
        },
        cli.BoolFlag{
+               Name:  "stats",
+               Usage: "accumulate stats",
+       },
+       cli.IntFlag{
+               Name:   "stats-n",
+               Usage:  "maximum number of stat entries",
+               Value:  15,
+               Hidden: true,
+       },
+       cli.BoolFlag{
                Name:  "filter-request",
                Usage: "trace calls only with request bytes greater than this 
threshold, use with filter-size",
        },
@@ -260,7 +275,7 @@
        responseSize uint64
 }
 
-func matchTrace(opts matchOpts, traceInfo madmin.ServiceTraceInfo) bool {
+func (opts matchOpts) matches(traceInfo madmin.ServiceTraceInfo) bool {
        // Filter request path if passed by the user
        if len(opts.apiPaths) > 0 {
                matched := false
@@ -450,14 +465,16 @@
        }
 
        for _, api := range apis {
-               fn, ok := traceCallTypes[api]
-               if !ok {
-                       fn, ok = traceCallTypeAliases[api]
-               }
-               if !ok {
-                       return madmin.ServiceTraceOpts{}, fmt.Errorf("unknown 
call name: `%s`", api)
+               for _, api := range strings.Split(api, ",") {
+                       fn, ok := traceCallTypes[api]
+                       if !ok {
+                               fn, ok = traceCallTypeAliases[api]
+                       }
+                       if !ok {
+                               return madmin.ServiceTraceOpts{}, 
fmt.Errorf("unknown call name: `%s`", api)
+                       }
+                       fn(&opts)
                }
-               fn(&opts)
        }
        return
 }
@@ -468,6 +485,7 @@
        checkAdminTraceSyntax(ctx)
 
        verbose := ctx.Bool("verbose")
+       stats := ctx.Bool("stats")
        aliasedURL := ctx.Args().Get(0)
 
        console.SetColor("Stat", color.New(color.FgYellow))
@@ -506,11 +524,27 @@
 
        // Start listening on all trace activity.
        traceCh := client.ServiceTrace(ctxt, opts)
+       if stats {
+               filteredTraces := make(chan madmin.ServiceTraceInfo, 1)
+               go func() {
+                       for t := range traceCh {
+                               if mopts.matches(t) {
+                                       filteredTraces <- t
+                               }
+                       }
+               }()
+               ui := tea.NewProgram(initTraceStatsUI(ctx.Int("stats-n"), 
filteredTraces))
+               if _, e := ui.Run(); e != nil {
+                       cancel()
+                       fatalIf(probe.NewError(e).Trace(aliasedURL), "Unable to 
fetch scanner metrics")
+               }
+               return nil
+       }
        for traceInfo := range traceCh {
                if traceInfo.Err != nil {
                        fatalIf(probe.NewError(traceInfo.Err), "Unable to 
listen to http trace")
                }
-               if matchTrace(mopts, traceInfo) {
+               if mopts.matches(traceInfo) {
                        printTrace(verbose, traceInfo)
                }
        }
@@ -842,3 +876,211 @@
        fmt.Fprint(b, nodeNameStr)
        return b.String()
 }
+
+type statItem struct {
+       Name           string
+       Count          int           `json:"count"`
+       Duration       time.Duration `json:"duration"`
+       Errors         int           `json:"errors,omitempty"`
+       CallStatsCount int           `json:"callStatsCount,omitempty"`
+       CallStats      callStats     `json:"callStats,omitempty"`
+}
+
+type statTrace struct {
+       Calls   map[string]statItem `json:"calls"`
+       Started time.Time
+       mu      sync.Mutex
+}
+
+func (s *statTrace) JSON() string {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+       buf := &bytes.Buffer{}
+       enc := json.NewEncoder(buf)
+       enc.SetIndent("", " ")
+       // Disable escaping special chars to display XML tags correctly
+       enc.SetEscapeHTML(false)
+       fatalIf(probe.NewError(enc.Encode(s)), "Unable to marshal into JSON.")
+
+       // strip off extra newline added by json encoder
+       return strings.TrimSuffix(buf.String(), "\n")
+}
+
+func (s *statTrace) String() string {
+       return ""
+}
+
+func (s *statTrace) add(t madmin.ServiceTraceInfo) {
+       id := t.Trace.FuncName
+       s.mu.Lock()
+       defer s.mu.Unlock()
+       got := s.Calls[id]
+       if got.Name == "" {
+               got.Name = id
+       }
+       got.Count++
+       got.Duration += t.Trace.Duration
+       if t.Trace.Error != "" {
+               got.Errors++
+       }
+       if t.Trace.HTTP != nil {
+               got.CallStatsCount++
+               got.CallStats.Rx += t.Trace.HTTP.CallStats.InputBytes
+               got.CallStats.Tx += t.Trace.HTTP.CallStats.OutputBytes
+       }
+       s.Calls[id] = got
+}
+
+func initTraceStatsUI(maxEntries int, traces <-chan madmin.ServiceTraceInfo) 
*traceStatsUI {
+       s := spinner.New()
+       s.Spinner = spinner.Points
+       s.Spinner.FPS = time.Second / 4
+       s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
+       console.SetColor("metrics-duration", color.New(color.FgWhite))
+       console.SetColor("metrics-dur", color.New(color.FgGreen))
+       console.SetColor("metrics-dur-med", color.New(color.FgYellow))
+       console.SetColor("metrics-dur-high", color.New(color.FgRed))
+       console.SetColor("metrics-error", color.New(color.FgYellow))
+       console.SetColor("metrics-title", color.New(color.FgCyan))
+       console.SetColor("metrics-top-title", color.New(color.FgHiCyan))
+       console.SetColor("metrics-number", color.New(color.FgWhite))
+       console.SetColor("metrics-number-secondary", color.New(color.FgBlue))
+       console.SetColor("metrics-zero", color.New(color.FgWhite))
+       stats := &statTrace{Calls: make(map[string]statItem, 20), Started: 
time.Now()}
+       go func() {
+               for t := range traces {
+                       stats.add(t)
+               }
+       }()
+       return &traceStatsUI{
+               started:    time.Now(),
+               spinner:    s,
+               maxEntries: maxEntries,
+               current:    stats,
+       }
+}
+
+type traceStatsUI struct {
+       current    *statTrace
+       started    time.Time
+       spinner    spinner.Model
+       quitting   bool
+       maxEntries int
+}
+
+func (m *traceStatsUI) Init() tea.Cmd {
+       return m.spinner.Tick
+}
+
+func (m *traceStatsUI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+       if m.quitting {
+               return m, tea.Quit
+       }
+       switch msg := msg.(type) {
+
+       case tea.KeyMsg:
+               switch msg.String() {
+               case "q", "esc", "ctrl+c":
+                       m.quitting = true
+                       return m, tea.Quit
+               default:
+                       return m, nil
+               }
+       case spinner.TickMsg:
+               var cmd tea.Cmd
+               m.spinner, cmd = m.spinner.Update(msg)
+               return m, cmd
+       }
+       return m, nil
+}
+
+func (m *traceStatsUI) View() string {
+       var s strings.Builder
+
+       if !m.quitting {
+               s.WriteString(fmt.Sprintf("%s %s\n", 
console.Colorize("metrics-top-title", "Duration: 
"+time.Since(m.current.Started).Round(time.Second).String()), m.spinner.View()))
+       }
+
+       // Set table header
+       table := tablewriter.NewWriter(&s)
+       table.SetAutoWrapText(false)
+       table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
+       table.SetAlignment(tablewriter.ALIGN_LEFT)
+       table.SetBorder(true)
+       table.SetRowLine(false)
+       addRow := func(s string) {
+               table.Append([]string{s})
+       }
+       _ = addRow
+       addRowF := func(format string, vals ...interface{}) {
+               s := fmt.Sprintf(format, vals...)
+               table.Append([]string{s})
+       }
+       _ = addRowF
+       var entries []statItem
+       m.current.mu.Lock()
+       totalCnt := 0
+       dur := time.Since(m.current.Started)
+       for _, v := range m.current.Calls {
+               totalCnt += v.Count
+               entries = append(entries, v)
+       }
+       m.current.mu.Unlock()
+       if len(entries) == 0 {
+               s.WriteString("(waiting for data)")
+               return s.String()
+       }
+       sort.Slice(entries, func(i, j int) bool {
+               if entries[i].Count == entries[j].Count {
+                       return entries[i].Name < entries[j].Name
+               }
+               return entries[i].Count > entries[j].Count
+       })
+       if m.maxEntries > 0 && len(entries) > m.maxEntries {
+               entries = entries[:m.maxEntries]
+       }
+
+       table.Append([]string{
+               console.Colorize("metrics-top-title", "Call"),
+               console.Colorize("metrics-top-title", "Count"),
+               console.Colorize("metrics-top-title", "RPM"),
+               console.Colorize("metrics-top-title", "Avg Time"),
+               console.Colorize("metrics-top-title", "Errors"),
+               console.Colorize("metrics-top-title", "RX Avg"),
+               console.Colorize("metrics-top-title", "TX Avg"),
+       })
+       for _, v := range entries {
+               if v.Count <= 0 {
+                       continue
+               }
+               errs := "0"
+               if v.Errors > 0 {
+                       errs = console.Colorize("metrics-error", 
fmt.Sprintf("%v", v.Errors))
+               }
+               avg := v.Duration / time.Duration(v.Count)
+               avgColor := "metrics-dur"
+               if avg > 10*time.Second {
+                       avgColor = "metrics-dur-high"
+               } else if avg > time.Second {
+                       avgColor = "metrics-dur-med"
+               }
+               rx := "-"
+               tx := "-"
+               if v.CallStatsCount > 0 {
+                       rx = humanize.IBytes(uint64(v.CallStats.Rx / 
v.CallStatsCount))
+                       tx = humanize.IBytes(uint64(v.CallStats.Tx / 
v.CallStatsCount))
+               }
+               table.Append([]string{
+                       console.Colorize("metrics-title", metricsTitle(v.Name)),
+                       console.Colorize("metrics-number", fmt.Sprintf("%d ", 
v.Count)) +
+                               console.Colorize("metrics-number-secondary", 
fmt.Sprintf("(%0.1f%%)", float64(v.Count)/float64(totalCnt)*100)),
+                       console.Colorize("metrics-number", fmt.Sprintf("%0.1f", 
float64(v.Count)/dur.Minutes())),
+                       console.Colorize(avgColor, fmt.Sprintf("%v", 
avg.Round(time.Microsecond))),
+                       errs,
+                       rx,
+                       tx,
+               })
+       }
+       table.Render()
+       return s.String()
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/common-methods.go 
new/mc-20231014T015703Z/cmd/common-methods.go
--- old/mc-20231004T065256Z/cmd/common-methods.go       2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/cmd/common-methods.go       2023-10-14 
03:57:03.000000000 +0200
@@ -108,12 +108,12 @@
 // Check if the passed URL represents a folder. It may or may not exist yet.
 // If it exists, we can easily check if it is a folder, if it doesn't exist,
 // we can guess if the url is a folder from how it looks.
-func isAliasURLDir(ctx context.Context, aliasURL string, keys 
map[string][]prefixSSEPair, timeRef time.Time) bool {
+func isAliasURLDir(ctx context.Context, aliasURL string, keys 
map[string][]prefixSSEPair, timeRef time.Time) (bool, *ClientContent) {
        // If the target url exists, check if it is a directory
        // and return immediately.
        _, targetContent, err := url2Stat(ctx, aliasURL, "", false, keys, 
timeRef, false)
        if err == nil {
-               return targetContent.Type.IsDir()
+               return targetContent.Type.IsDir(), targetContent
        }
 
        _, expandedURL, _ := mustExpandAlias(aliasURL)
@@ -121,7 +121,7 @@
        // Check if targetURL is an FS or S3 aliased url
        if expandedURL == aliasURL {
                // This is an FS url, check if the url has a separator at the 
end
-               return strings.HasSuffix(aliasURL, string(filepath.Separator))
+               return strings.HasSuffix(aliasURL, string(filepath.Separator)), 
targetContent
        }
 
        // This is an S3 url, then:
@@ -134,14 +134,14 @@
        switch len(fields) {
        // Nothing or alias format
        case 0, 1:
-               return false
+               return false, targetContent
        // alias/bucket format
        case 2:
-               return true
+               return true, targetContent
        } // default case..
 
        // alias/bucket/prefix format
-       return strings.HasSuffix(pathURL, "/")
+       return strings.HasSuffix(pathURL, "/"), targetContent
 }
 
 // getSourceStreamMetadataFromURL gets a reader from URL.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/cp-main.go 
new/mc-20231014T015703Z/cmd/cp-main.go
--- old/mc-20231004T065256Z/cmd/cp-main.go      2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/cp-main.go      2023-10-14 03:57:03.000000000 
+0200
@@ -288,7 +288,7 @@
 }
 
 // doPrepareCopyURLs scans the source URL and prepares a list of objects for 
copying.
-func doPrepareCopyURLs(ctx context.Context, session *sessionV8, cancelCopy 
context.CancelFunc) (totalBytes, totalObjects int64) {
+func doPrepareCopyURLs(ctx context.Context, session *sessionV8, cancelCopy 
context.CancelFunc) (totalBytes, totalObjects int64, errSeen bool) {
        // Separate source and target. 'cp' can take only one target,
        // but any number of sources.
        sourceURLs := 
session.Header.CommandArgs[:len(session.Header.CommandArgs)-1]
@@ -333,16 +333,10 @@
                                done = true
                                break
                        }
+
                        if cpURLs.Error != nil {
-                               // Print in new line and adjust to top so that 
we don't print over the ongoing scan bar
-                               if !globalQuiet && !globalJSON {
-                                       console.Eraseline()
-                               }
-                               if 
strings.Contains(cpURLs.Error.ToGoError().Error(), " is a folder.") {
-                                       errorIf(cpURLs.Error.Trace(), "Folder 
cannot be copied. Please use `...` suffix.")
-                               } else {
-                                       errorIf(cpURLs.Error.Trace(), "Unable 
to prepare URL for copying.")
-                               }
+                               printCopyURLsError(&cpURLs)
+                               errSeen = true
                                break
                        }
 
@@ -377,11 +371,29 @@
        return
 }
 
+func printCopyURLsError(cpURLs *URLs) {
+       // Print in new line and adjust to top so that we
+       // don't print over the ongoing scan bar
+       if !globalQuiet && !globalJSON {
+               console.Eraseline()
+       }
+
+       if strings.Contains(cpURLs.Error.ToGoError().Error(),
+               " is a folder.") {
+               errorIf(cpURLs.Error.Trace(),
+                       "Folder cannot be copied. Please use `...` suffix.")
+       } else {
+               errorIf(cpURLs.Error.Trace(),
+                       "Unable to prepare URL for copying.")
+       }
+}
+
 func doCopySession(ctx context.Context, cancelCopy context.CancelFunc, cli 
*cli.Context, session *sessionV8, encKeyDB map[string][]prefixSSEPair, isMvCmd 
bool) error {
        var isCopied func(string) bool
        var totalObjects, totalBytes int64
 
        cpURLsCh := make(chan URLs, 10000)
+       errSeen := false
 
        // Store a progress bar or an accounter
        var pg ProgressReader
@@ -405,7 +417,7 @@
                isCopied = isLastFactory(session.Header.LastCopied)
 
                if !session.HasData() {
-                       totalBytes, totalObjects = doPrepareCopyURLs(ctx, 
session, cancelCopy)
+                       totalBytes, totalObjects, errSeen = 
doPrepareCopyURLs(ctx, session, cancelCopy)
                } else {
                        totalBytes, totalObjects = session.Header.TotalBytes, 
session.Header.TotalObjects
                }
@@ -431,6 +443,7 @@
                                cpURLsCh <- cpURLs
                        }
                }()
+
        } else {
                // Access recursive flag inside the session header.
                isRecursive := cli.Bool("recursive")
@@ -452,23 +465,14 @@
                                versionID:   versionID,
                                isZip:       cli.Bool("zip"),
                        }
+
                        for cpURLs := range prepareCopyURLs(ctx, opts) {
                                if cpURLs.Error != nil {
-                                       // Print in new line and adjust to top 
so that we
-                                       // don't print over the ongoing scan bar
-                                       if !globalQuiet && !globalJSON {
-                                               console.Eraseline()
-                                       }
-                                       if 
strings.Contains(cpURLs.Error.ToGoError().Error(),
-                                               " is a folder.") {
-                                               errorIf(cpURLs.Error.Trace(),
-                                                       "Folder cannot be 
copied. Please use `...` suffix.")
-                                       } else {
-                                               errorIf(cpURLs.Error.Trace(),
-                                                       "Unable to start 
copying.")
-                                       }
+                                       errSeen = true
+                                       printCopyURLsError(&cpURLs)
                                        break
                                }
+
                                totalBytes += cpURLs.SourceContent.Size
                                pg.SetTotal(totalBytes)
                                totalObjects++
@@ -570,7 +574,6 @@
        }()
 
        var retErr error
-       errSeen := false
        cpAllFilesErr := true
 
 loop:
@@ -639,14 +642,24 @@
        }
 
        if progressReader, ok := pg.(*progressBar); ok {
-               if (errSeen && totalObjects == 1) || (cpAllFilesErr && 
totalObjects > 1) {
-                       console.Eraseline()
+               if errSeen || (cpAllFilesErr && totalObjects > 0) {
+                       // We only erase a line if we are displaying a progress 
bar
+                       if !globalQuiet && !globalJSON {
+                               console.Eraseline()
+                       }
                } else if progressReader.ProgressBar.Get() > 0 {
                        progressReader.ProgressBar.Finish()
                }
        } else {
                if accntReader, ok := pg.(*accounter); ok {
-                       printMsg(accntReader.Stat())
+                       if errSeen || (cpAllFilesErr && totalObjects > 0) {
+                               // We only erase a line if we are displaying a 
progress bar
+                               if !globalQuiet && !globalJSON {
+                                       console.Eraseline()
+                               }
+                       } else {
+                               printMsg(accntReader.Stat())
+                       }
                }
        }
 
@@ -670,7 +683,7 @@
        }
 
        // check 'copy' cli arguments.
-       checkCopySyntax(ctx, cliCtx, encKeyDB, false)
+       checkCopySyntax(cliCtx)
        // Additional command specific theme customization.
        console.SetColor("Copy", color.New(color.FgGreen, color.Bold))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/cp-url-syntax.go 
new/mc-20231014T015703Z/cmd/cp-url-syntax.go
--- old/mc-20231004T065256Z/cmd/cp-url-syntax.go        2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/cmd/cp-url-syntax.go        2023-10-14 
03:57:03.000000000 +0200
@@ -18,21 +18,14 @@
 package cmd
 
 import (
-       "context"
        "fmt"
        "runtime"
-       "time"
 
        "github.com/minio/cli"
-       "github.com/minio/mc/pkg/probe"
-       "github.com/minio/pkg/v2/console"
 )
 
-func checkCopySyntax(ctx context.Context, cliCtx *cli.Context, encKeyDB 
map[string][]prefixSSEPair, isMvCmd bool) {
+func checkCopySyntax(cliCtx *cli.Context) {
        if len(cliCtx.Args()) < 2 {
-               if isMvCmd {
-                       showCommandHelpAndExit(cliCtx, 1) // last argument is 
exit code.
-               }
                showCommandHelpAndExit(cliCtx, 1) // last argument is exit code.
        }
 
@@ -44,9 +37,7 @@
 
        srcURLs := URLs[:len(URLs)-1]
        tgtURL := URLs[len(URLs)-1]
-       isRecursive := cliCtx.Bool("recursive")
        isZip := cliCtx.Bool("zip")
-       timeRef := parseRewindFlag(cliCtx.String("rewind"))
        versionID := cliCtx.String("version-id")
 
        if versionID != "" && len(srcURLs) > 1 {
@@ -57,24 +48,6 @@
                fatalIf(errDummy().Trace(cliCtx.Args()...), "--zip and --rewind 
cannot be used together")
        }
 
-       // Verify if source(s) exists.
-       for _, srcURL := range srcURLs {
-               var err *probe.Error
-               if !isRecursive {
-                       _, _, err = url2Stat(ctx, srcURL, versionID, false, 
encKeyDB, timeRef, isZip)
-               } else {
-                       _, _, err = firstURL2Stat(ctx, srcURL, timeRef, isZip)
-               }
-               if err != nil {
-                       msg := "Unable to validate source `" + srcURL + "`"
-                       if versionID != "" {
-                               msg += " (" + versionID + ")"
-                       }
-                       msg += ": " + err.ToGoError().Error()
-                       console.Fatalln(msg)
-               }
-       }
-
        // Check if bucket name is passed for URL type arguments.
        url := newClientURL(tgtURL)
        if url.Host != "" {
@@ -91,129 +64,8 @@
                fatalIf(errInvalidArgument().Trace(), fmt.Sprintf("Both object 
retention flags `--%s` and `--%s` are required.\n", rdFlag, rmFlag))
        }
 
-       operation := "copy"
-       if isMvCmd {
-               operation = "move"
-       }
-
-       // Guess CopyURLsType based on source and target URLs.
-       opts := prepareCopyURLsOpts{
-               sourceURLs:  srcURLs,
-               targetURL:   tgtURL,
-               isRecursive: isRecursive,
-               encKeyDB:    encKeyDB,
-               olderThan:   "",
-               newerThan:   "",
-               timeRef:     timeRef,
-               versionID:   versionID,
-               isZip:       isZip,
-       }
-       copyURLsType, _, err := guessCopyURLType(ctx, opts)
-       if err != nil {
-               fatalIf(errInvalidArgument().Trace(), "Unable to guess the type 
of "+operation+" operation.")
-       }
-
-       switch copyURLsType {
-       case copyURLsTypeA: // File -> File.
-               // Check source.
-               if len(srcURLs) != 1 {
-                       fatalIf(errInvalidArgument().Trace(), "Invalid number 
of source arguments.")
-               }
-               checkCopySyntaxTypeA(ctx, srcURLs[0], versionID, encKeyDB, 
isZip, timeRef)
-       case copyURLsTypeB: // File -> Folder.
-               // Check source.
-               if len(srcURLs) != 1 {
-                       fatalIf(errInvalidArgument().Trace(), "Invalid number 
of source arguments.")
-               }
-               checkCopySyntaxTypeB(ctx, srcURLs[0], versionID, tgtURL, 
encKeyDB, isZip, timeRef)
-       case copyURLsTypeC: // Folder... -> Folder.
-               checkCopySyntaxTypeC(ctx, srcURLs, tgtURL, isRecursive, isZip, 
encKeyDB, isMvCmd, timeRef)
-       case copyURLsTypeD: // File1...FileN -> Folder.
-               checkCopySyntaxTypeD(ctx, tgtURL, encKeyDB, timeRef)
-       default:
-               fatalIf(errInvalidArgument().Trace(), "Unable to guess the type 
of "+operation+" operation.")
-       }
-
        // Preserve functionality not supported for windows
        if cliCtx.Bool("preserve") && runtime.GOOS == "windows" {
                fatalIf(errInvalidArgument().Trace(), "Permissions are not 
preserved on windows platform.")
        }
 }
-
-// checkCopySyntaxTypeA verifies if the source and target are valid file 
arguments.
-func checkCopySyntaxTypeA(ctx context.Context, srcURL, versionID string, keys 
map[string][]prefixSSEPair, isZip bool, timeRef time.Time) {
-       _, srcContent, err := url2Stat(ctx, srcURL, versionID, false, keys, 
timeRef, isZip)
-       fatalIf(err.Trace(srcURL), "Unable to stat source `"+srcURL+"`.")
-
-       if !srcContent.Type.IsRegular() {
-               fatalIf(errInvalidArgument().Trace(), "Source `"+srcURL+"` is 
not a file.")
-       }
-}
-
-// checkCopySyntaxTypeB verifies if the source is a valid file and target is a 
valid folder.
-func checkCopySyntaxTypeB(ctx context.Context, srcURL, versionID, tgtURL 
string, keys map[string][]prefixSSEPair, isZip bool, timeRef time.Time) {
-       _, srcContent, err := url2Stat(ctx, srcURL, versionID, false, keys, 
timeRef, isZip)
-       fatalIf(err.Trace(srcURL), "Unable to stat source `"+srcURL+"`.")
-
-       if !srcContent.Type.IsRegular() {
-               fatalIf(errInvalidArgument().Trace(srcURL), "Source 
`"+srcURL+"` is not a file.")
-       }
-
-       // Check target.
-       if _, tgtContent, err := url2Stat(ctx, tgtURL, "", false, keys, 
timeRef, false); err == nil {
-               if !tgtContent.Type.IsDir() {
-                       fatalIf(errInvalidArgument().Trace(tgtURL), "Target 
`"+tgtURL+"` is not a folder.")
-               }
-       }
-}
-
-// checkCopySyntaxTypeC verifies if the source is a valid recursive dir and 
target is a valid folder.
-func checkCopySyntaxTypeC(ctx context.Context, srcURLs []string, tgtURL 
string, isRecursive, isZip bool, keys map[string][]prefixSSEPair, isMvCmd bool, 
timeRef time.Time) {
-       // Check source.
-       if len(srcURLs) != 1 {
-               fatalIf(errInvalidArgument().Trace(), "Invalid number of source 
arguments.")
-       }
-
-       // Check target.
-       if _, tgtContent, err := url2Stat(ctx, tgtURL, "", false, keys, 
timeRef, false); err == nil {
-               if !tgtContent.Type.IsDir() {
-                       fatalIf(errInvalidArgument().Trace(tgtURL), "Target 
`"+tgtURL+"` is not a folder.")
-               }
-       }
-
-       for _, srcURL := range srcURLs {
-               c, srcContent, err := url2Stat(ctx, srcURL, "", false, keys, 
timeRef, isZip)
-               fatalIf(err.Trace(srcURL), "Unable to stat source 
`"+srcURL+"`.")
-
-               if srcContent.Type.IsDir() {
-                       // Require --recursive flag if we are copying a 
directory
-                       if !isRecursive {
-                               operation := "copy"
-                               if isMvCmd {
-                                       operation = "move"
-                               }
-                               fatalIf(errInvalidArgument().Trace(srcURL), 
fmt.Sprintf("To %v a folder requires --recursive flag.", operation))
-                       }
-
-                       // Check if we are going to copy a directory into itself
-                       if isURLContains(srcURL, tgtURL, 
string(c.GetURL().Separator)) {
-                               operation := "Copying"
-                               if isMvCmd {
-                                       operation = "Moving"
-                               }
-                               fatalIf(errInvalidArgument().Trace(), 
fmt.Sprintf("%v a folder into itself is not allowed.", operation))
-                       }
-               }
-       }
-}
-
-// checkCopySyntaxTypeD verifies if the source is a valid list of files and 
target is a valid folder.
-func checkCopySyntaxTypeD(ctx context.Context, tgtURL string, keys 
map[string][]prefixSSEPair, timeRef time.Time) {
-       // Source can be anything: file, dir, dir...
-       // Check target if it is a dir
-       if _, tgtContent, err := url2Stat(ctx, tgtURL, "", false, keys, 
timeRef, false); err == nil {
-               if !tgtContent.Type.IsDir() {
-                       fatalIf(errInvalidArgument().Trace(tgtURL), "Target 
`"+tgtURL+"` is not a folder.")
-               }
-       }
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/cp-url.go 
new/mc-20231014T015703Z/cmd/cp-url.go
--- old/mc-20231004T065256Z/cmd/cp-url.go       2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/cp-url.go       2023-10-14 03:57:03.000000000 
+0200
@@ -53,127 +53,182 @@
 
 // guessCopyURLType guesses the type of clientURL. This approach all allows 
prepareURL
 // functions to accurately report failure causes.
-func guessCopyURLType(ctx context.Context, o prepareCopyURLsOpts) 
(copyURLsType, string, *probe.Error) {
+func guessCopyURLType(ctx context.Context, o prepareCopyURLsOpts) 
(*copyURLsContent, *probe.Error) {
+       cc := new(copyURLsContent)
+
+       // Extract alias before fiddling with the clientURL.
+       cc.sourceURL = o.sourceURLs[0]
+       cc.sourceAlias, _, _ = mustExpandAlias(cc.sourceURL)
+       // Find alias and expanded clientURL.
+       cc.targetAlias, cc.targetURL, _ = mustExpandAlias(o.targetURL)
+
        if len(o.sourceURLs) == 1 { // 1 Source, 1 Target
                var err *probe.Error
-               var sourceContent *ClientContent
-               sourceURL := o.sourceURLs[0]
                if !o.isRecursive {
-                       _, sourceContent, err = url2Stat(ctx, sourceURL, 
o.versionID, false, o.encKeyDB, o.timeRef, o.isZip)
+                       _, cc.sourceContent, err = url2Stat(ctx, cc.sourceURL, 
o.versionID, false, o.encKeyDB, o.timeRef, o.isZip)
                } else {
-                       _, sourceContent, err = firstURL2Stat(ctx, sourceURL, 
o.timeRef, o.isZip)
+                       _, cc.sourceContent, err = firstURL2Stat(ctx, 
cc.sourceURL, o.timeRef, o.isZip)
                }
+
                if err != nil {
-                       return copyURLsTypeInvalid, "", err
+                       cc.copyType = copyURLsTypeInvalid
+                       return cc, err
                }
 
                // If recursion is ON, it is type C.
                // If source is a folder, it is Type C.
-               if sourceContent.Type.IsDir() || o.isRecursive {
-                       return copyURLsTypeC, "", nil
+               if cc.sourceContent.Type.IsDir() || o.isRecursive {
+                       cc.copyType = copyURLsTypeC
+                       return cc, nil
                }
 
                // If target is a folder, it is Type B.
-               if isAliasURLDir(ctx, o.targetURL, o.encKeyDB, o.timeRef) {
-                       return copyURLsTypeB, sourceContent.VersionID, nil
+               var isDir bool
+               isDir, cc.targetContent = isAliasURLDir(ctx, o.targetURL, 
o.encKeyDB, o.timeRef)
+               if isDir {
+                       cc.copyType = copyURLsTypeB
+                       cc.sourceVersionID = cc.sourceContent.VersionID
+                       return cc, nil
                }
+
                // else Type A.
-               return copyURLsTypeA, sourceContent.VersionID, nil
+               cc.copyType = copyURLsTypeA
+               cc.sourceVersionID = cc.sourceContent.VersionID
+               return cc, nil
        }
 
+       var isDir bool
        // Multiple source args and target is a folder. It is Type D.
-       if isAliasURLDir(ctx, o.targetURL, o.encKeyDB, o.timeRef) {
-               return copyURLsTypeD, "", nil
+       isDir, cc.targetContent = isAliasURLDir(ctx, o.targetURL, o.encKeyDB, 
o.timeRef)
+       if isDir {
+               cc.copyType = copyURLsTypeD
+               return cc, nil
        }
 
-       return copyURLsTypeInvalid, "", errInvalidArgument().Trace()
+       cc.copyType = copyURLsTypeInvalid
+       return cc, errInvalidArgument().Trace()
 }
 
 // SINGLE SOURCE - Type A: copy(f, f) -> copy(f, f)
 // prepareCopyURLsTypeA - prepares target and source clientURLs for copying.
-func prepareCopyURLsTypeA(ctx context.Context, sourceURL, sourceVersion, 
targetURL string, encKeyDB map[string][]prefixSSEPair, isZip bool) URLs {
-       // Extract alias before fiddling with the clientURL.
-       sourceAlias, _, _ := mustExpandAlias(sourceURL)
-       // Find alias and expanded clientURL.
-       targetAlias, targetURL, _ := mustExpandAlias(targetURL)
-
-       _, sourceContent, err := url2Stat(ctx, sourceURL, sourceVersion, false, 
encKeyDB, time.Time{}, isZip)
-       if err != nil {
-               // Source does not exist or insufficient privileges.
-               return URLs{Error: err.Trace(sourceURL)}
+func prepareCopyURLsTypeA(ctx context.Context, cc copyURLsContent, o 
prepareCopyURLsOpts) URLs {
+       var err *probe.Error
+       if cc.sourceContent == nil {
+               _, cc.sourceContent, err = url2Stat(ctx, cc.sourceURL, 
cc.sourceVersionID, false, o.encKeyDB, time.Time{}, o.isZip)
+               if err != nil {
+                       // Source does not exist or insufficient privileges.
+                       return URLs{Error: err.Trace(cc.sourceURL)}
+               }
        }
-       if !sourceContent.Type.IsRegular() {
+
+       if !cc.sourceContent.Type.IsRegular() {
                // Source is not a regular file
-               return URLs{Error: errInvalidSource(sourceURL).Trace(sourceURL)}
+               return URLs{Error: 
errInvalidSource(cc.sourceURL).Trace(cc.sourceURL)}
        }
-
        // All OK.. We can proceed. Type A
-       return makeCopyContentTypeA(sourceAlias, sourceContent, targetAlias, 
targetURL)
+       return makeCopyContentTypeA(cc)
 }
 
 // prepareCopyContentTypeA - makes CopyURLs content for copying.
-func makeCopyContentTypeA(sourceAlias string, sourceContent *ClientContent, 
targetAlias, targetURL string) URLs {
-       targetContent := ClientContent{URL: *newClientURL(targetURL)}
+func makeCopyContentTypeA(cc copyURLsContent) URLs {
+       targetContent := ClientContent{URL: *newClientURL(cc.targetURL)}
        return URLs{
-               SourceAlias:   sourceAlias,
-               SourceContent: sourceContent,
-               TargetAlias:   targetAlias,
+               SourceAlias:   cc.sourceAlias,
+               SourceContent: cc.sourceContent,
+               TargetAlias:   cc.targetAlias,
                TargetContent: &targetContent,
        }
 }
 
 // SINGLE SOURCE - Type B: copy(f, d) -> copy(f, d/f) -> A
 // prepareCopyURLsTypeB - prepares target and source clientURLs for copying.
-func prepareCopyURLsTypeB(ctx context.Context, sourceURL, sourceVersion, 
targetURL string, encKeyDB map[string][]prefixSSEPair, isZip bool) URLs {
-       // Extract alias before fiddling with the clientURL.
-       sourceAlias, _, _ := mustExpandAlias(sourceURL)
-       // Find alias and expanded clientURL.
-       targetAlias, targetURL, _ := mustExpandAlias(targetURL)
-
-       _, sourceContent, err := url2Stat(ctx, sourceURL, sourceVersion, false, 
encKeyDB, time.Time{}, isZip)
-       if err != nil {
-               // Source does not exist or insufficient privileges.
-               return URLs{Error: err.Trace(sourceURL)}
+func prepareCopyURLsTypeB(ctx context.Context, cc copyURLsContent, o 
prepareCopyURLsOpts) URLs {
+       var err *probe.Error
+       if cc.sourceContent == nil {
+               _, cc.sourceContent, err = url2Stat(ctx, cc.sourceURL, 
cc.sourceVersionID, false, o.encKeyDB, time.Time{}, o.isZip)
+               if err != nil {
+                       // Source does not exist or insufficient privileges.
+                       return URLs{Error: err.Trace(cc.sourceURL)}
+               }
        }
 
-       if !sourceContent.Type.IsRegular() {
-               if sourceContent.Type.IsDir() {
-                       return URLs{Error: 
errSourceIsDir(sourceURL).Trace(sourceURL)}
+       if !cc.sourceContent.Type.IsRegular() {
+               if cc.sourceContent.Type.IsDir() {
+                       return URLs{Error: 
errSourceIsDir(cc.sourceURL).Trace(cc.sourceURL)}
                }
                // Source is not a regular file.
-               return URLs{Error: errInvalidSource(sourceURL).Trace(sourceURL)}
+               return URLs{Error: 
errInvalidSource(cc.sourceURL).Trace(cc.sourceURL)}
        }
 
+       if cc.targetContent == nil {
+               _, cc.targetContent, err = url2Stat(ctx, cc.targetURL, "", 
false, o.encKeyDB, time.Time{}, false)
+               if err == nil {
+                       if !cc.targetContent.Type.IsDir() {
+                               return URLs{Error: 
errInvalidTarget(cc.targetURL).Trace(cc.targetURL)}
+                       }
+               }
+       }
        // All OK.. We can proceed. Type B: source is a file, target is a 
folder and exists.
-       return makeCopyContentTypeB(sourceAlias, sourceContent, targetAlias, 
targetURL)
+       return makeCopyContentTypeB(cc)
 }
 
 // makeCopyContentTypeB - CopyURLs content for copying.
-func makeCopyContentTypeB(sourceAlias string, sourceContent *ClientContent, 
targetAlias, targetURL string) URLs {
+func makeCopyContentTypeB(cc copyURLsContent) URLs {
        // All OK.. We can proceed. Type B: source is a file, target is a 
folder and exists.
-       targetURLParse := newClientURL(targetURL)
-       targetURLParse.Path = 
filepath.ToSlash(filepath.Join(targetURLParse.Path, 
filepath.Base(sourceContent.URL.Path)))
-       return makeCopyContentTypeA(sourceAlias, sourceContent, targetAlias, 
targetURLParse.String())
+       targetURLParse := newClientURL(cc.targetURL)
+       targetURLParse.Path = 
filepath.ToSlash(filepath.Join(targetURLParse.Path, 
filepath.Base(cc.sourceContent.URL.Path)))
+       cc.targetURL = targetURLParse.String()
+       return makeCopyContentTypeA(cc)
 }
 
 // SINGLE SOURCE - Type C: copy(d1..., d2) -> []copy(d1/f, d1/d2/f) -> []A
 // prepareCopyRecursiveURLTypeC - prepares target and source clientURLs for 
copying.
-func prepareCopyURLsTypeC(ctx context.Context, sourceURL, targetURL string, 
isRecursive, isZip bool, timeRef time.Time) <-chan URLs {
-       // Extract alias before fiddling with the clientURL.
-       sourceAlias, _, _ := mustExpandAlias(sourceURL)
-       // Find alias and expanded clientURL.
-       targetAlias, targetURL, _ := mustExpandAlias(targetURL)
-       copyURLsCh := make(chan URLs)
-       go func(sourceURL, targetURL string, copyURLsCh chan URLs) {
-               defer close(copyURLsCh)
-               sourceClient, err := newClient(sourceURL)
+func prepareCopyURLsTypeC(ctx context.Context, cc copyURLsContent, o 
prepareCopyURLsOpts) <-chan URLs {
+       copyURLsCh := make(chan URLs, 1)
+
+       returnErrorAndCloseChannel := func(err *probe.Error) chan URLs {
+               copyURLsCh <- URLs{Error: err}
+               close(copyURLsCh)
+               return copyURLsCh
+       }
+
+       c, err := newClient(cc.sourceURL)
+       if err != nil {
+               return returnErrorAndCloseChannel(err.Trace(cc.sourceURL))
+       }
+
+       if cc.targetContent == nil {
+               _, cc.targetContent, err = url2Stat(ctx, cc.targetURL, "", 
false, o.encKeyDB, time.Time{}, o.isZip)
+               if err == nil {
+                       if !cc.targetContent.Type.IsDir() {
+                               return 
returnErrorAndCloseChannel(errTargetIsNotDir(cc.targetURL).Trace(cc.targetURL))
+                       }
+               }
+       }
+
+       if cc.sourceContent == nil {
+               _, cc.sourceContent, err = url2Stat(ctx, cc.sourceURL, "", 
false, o.encKeyDB, time.Time{}, o.isZip)
                if err != nil {
-                       // Source initialization failed.
-                       copyURLsCh <- URLs{Error: err.Trace(sourceURL)}
-                       return
+                       return 
returnErrorAndCloseChannel(err.Trace(cc.sourceURL))
                }
+       }
 
-               for sourceContent := range sourceClient.List(ctx, 
ListOptions{Recursive: isRecursive, TimeRef: timeRef, ShowDir: DirNone, 
ListZip: isZip}) {
+       if cc.sourceContent.Type.IsDir() {
+               // Require --recursive flag if we are copying a directory
+               if !o.isRecursive {
+                       return 
returnErrorAndCloseChannel(errRequiresRecursive(cc.sourceURL).Trace(cc.sourceURL))
+               }
+
+               // Check if we are going to copy a directory into itself
+               if isURLContains(cc.sourceURL, cc.targetURL, 
string(c.GetURL().Separator)) {
+                       return 
returnErrorAndCloseChannel(errCopyIntoSelf(cc.sourceURL).Trace(cc.targetURL))
+               }
+       }
+
+       go func(sourceClient Client, cc copyURLsContent, o prepareCopyURLsOpts, 
copyURLsCh chan URLs) {
+               defer close(copyURLsCh)
+
+               for sourceContent := range sourceClient.List(ctx, 
ListOptions{Recursive: o.isRecursive, TimeRef: o.timeRef, ShowDir: DirNone, 
ListZip: o.isZip}) {
                        if sourceContent.Err != nil {
                                // Listing failed.
                                copyURLsCh <- URLs{Error: 
sourceContent.Err.Trace(sourceClient.GetURL().String())}
@@ -185,38 +240,50 @@
                                continue
                        }
 
+                       // Clone cc
+                       newCC := cc
+                       newCC.sourceContent = sourceContent
                        // All OK.. We can proceed. Type B: source is a file, 
target is a folder and exists.
-                       copyURLsCh <- makeCopyContentTypeC(sourceAlias, 
sourceClient.GetURL(), sourceContent, targetAlias, targetURL)
+                       copyURLsCh <- makeCopyContentTypeC(newCC, 
sourceClient.GetURL())
                }
-       }(sourceURL, targetURL, copyURLsCh)
+       }(c, cc, o, copyURLsCh)
+
        return copyURLsCh
 }
 
 // makeCopyContentTypeC - CopyURLs content for copying.
-func makeCopyContentTypeC(sourceAlias string, sourceURL ClientURL, 
sourceContent *ClientContent, targetAlias, targetURL string) URLs {
-       newSourceURL := sourceContent.URL
-       pathSeparatorIndex := strings.LastIndex(sourceURL.Path, 
string(sourceURL.Separator))
+func makeCopyContentTypeC(cc copyURLsContent, sourceClientURL ClientURL) URLs {
+       newSourceURL := cc.sourceContent.URL
+       pathSeparatorIndex := strings.LastIndex(sourceClientURL.Path, 
string(sourceClientURL.Separator))
        newSourceSuffix := filepath.ToSlash(newSourceURL.Path)
        if pathSeparatorIndex > 1 {
-               sourcePrefix := 
filepath.ToSlash(sourceURL.Path[:pathSeparatorIndex])
+               sourcePrefix := 
filepath.ToSlash(sourceClientURL.Path[:pathSeparatorIndex])
                newSourceSuffix = strings.TrimPrefix(newSourceSuffix, 
sourcePrefix)
        }
-       newTargetURL := urlJoinPath(targetURL, newSourceSuffix)
-       return makeCopyContentTypeA(sourceAlias, sourceContent, targetAlias, 
newTargetURL)
+       newTargetURL := urlJoinPath(cc.targetURL, newSourceSuffix)
+       cc.targetURL = newTargetURL
+       return makeCopyContentTypeA(cc)
 }
 
 // MULTI-SOURCE - Type D: copy([](f|d...), d) -> []B
 // prepareCopyURLsTypeE - prepares target and source clientURLs for copying.
-func prepareCopyURLsTypeD(ctx context.Context, sourceURLs []string, targetURL 
string, isRecursive bool, timeRef time.Time) <-chan URLs {
-       copyURLsCh := make(chan URLs)
-       go func(sourceURLs []string, targetURL string, copyURLsCh chan URLs) {
+func prepareCopyURLsTypeD(ctx context.Context, cc copyURLsContent, o 
prepareCopyURLsOpts) <-chan URLs {
+       copyURLsCh := make(chan URLs, 1)
+
+       go func(ctx context.Context, cc copyURLsContent, o prepareCopyURLsOpts) 
{
                defer close(copyURLsCh)
-               for _, sourceURL := range sourceURLs {
-                       for cpURLs := range prepareCopyURLsTypeC(ctx, 
sourceURL, targetURL, isRecursive, false, timeRef) {
+
+               for _, sourceURL := range o.sourceURLs {
+                       // Clone CC
+                       newCC := cc
+                       newCC.sourceURL = sourceURL
+
+                       for cpURLs := range prepareCopyURLsTypeC(ctx, newCC, o) 
{
                                copyURLsCh <- cpURLs
                        }
                }
-       }(sourceURLs, targetURL, copyURLsCh)
+       }(ctx, cc, o)
+
        return copyURLsCh
 }
 
@@ -231,25 +298,39 @@
        isZip                bool
 }
 
+type copyURLsContent struct {
+       targetContent   *ClientContent
+       targetAlias     string
+       targetURL       string
+       sourceContent   *ClientContent
+       sourceAlias     string
+       sourceURL       string
+       copyType        copyURLsType
+       sourceVersionID string
+}
+
 // prepareCopyURLs - prepares target and source clientURLs for copying.
 func prepareCopyURLs(ctx context.Context, o prepareCopyURLsOpts) chan URLs {
        copyURLsCh := make(chan URLs)
        go func(o prepareCopyURLsOpts) {
                defer close(copyURLsCh)
-               cpType, cpVersion, err := guessCopyURLType(ctx, o)
-               fatalIf(err.Trace(), "Unable to guess the type of copy 
operation.")
+               copyURLsContent, err := guessCopyURLType(ctx, o)
+               if err != nil {
+                       copyURLsCh <- URLs{Error: 
errUnableToGuess().Trace(o.sourceURLs...)}
+                       return
+               }
 
-               switch cpType {
+               switch copyURLsContent.copyType {
                case copyURLsTypeA:
-                       copyURLsCh <- prepareCopyURLsTypeA(ctx, 
o.sourceURLs[0], cpVersion, o.targetURL, o.encKeyDB, o.isZip)
+                       copyURLsCh <- prepareCopyURLsTypeA(ctx, 
*copyURLsContent, o)
                case copyURLsTypeB:
-                       copyURLsCh <- prepareCopyURLsTypeB(ctx, 
o.sourceURLs[0], cpVersion, o.targetURL, o.encKeyDB, o.isZip)
+                       copyURLsCh <- prepareCopyURLsTypeB(ctx, 
*copyURLsContent, o)
                case copyURLsTypeC:
-                       for cURLs := range prepareCopyURLsTypeC(ctx, 
o.sourceURLs[0], o.targetURL, o.isRecursive, o.isZip, o.timeRef) {
+                       for cURLs := range prepareCopyURLsTypeC(ctx, 
*copyURLsContent, o) {
                                copyURLsCh <- cURLs
                        }
                case copyURLsTypeD:
-                       for cURLs := range prepareCopyURLsTypeD(ctx, 
o.sourceURLs, o.targetURL, o.isRecursive, o.timeRef) {
+                       for cURLs := range prepareCopyURLsTypeD(ctx, 
*copyURLsContent, o) {
                                copyURLsCh <- cURLs
                        }
                default:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/du-main.go 
new/mc-20231014T015703Z/cmd/du-main.go
--- old/mc-20231004T065256Z/cmd/du-main.go      2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/du-main.go      2023-10-14 03:57:03.000000000 
+0200
@@ -243,8 +243,10 @@
        timeRef := parseRewindFlag(cliCtx.String("rewind"))
 
        var duErr error
+       var isDir bool
        for _, urlStr := range cliCtx.Args() {
-               if !isAliasURLDir(ctx, urlStr, nil, time.Time{}) {
+               isDir, _ = isAliasURLDir(ctx, urlStr, nil, time.Time{})
+               if !isDir {
                        fatalIf(errInvalidArgument().Trace(urlStr), 
fmt.Sprintf("Source `%s` is not a folder. Only folders are supported by 'du' 
command.", urlStr))
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/mv-main.go 
new/mc-20231014T015703Z/cmd/mv-main.go
--- old/mc-20231004T065256Z/cmd/mv-main.go      2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/mv-main.go      2023-10-14 03:57:03.000000000 
+0200
@@ -227,7 +227,7 @@
        }
 
        // check 'copy' cli arguments.
-       checkCopySyntax(ctx, cliCtx, encKeyDB, true)
+       checkCopySyntax(cliCtx)
 
        if cliCtx.NArg() == 2 {
                args := cliCtx.Args()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/od-main.go 
new/mc-20231014T015703Z/cmd/od-main.go
--- old/mc-20231004T065256Z/cmd/od-main.go      2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/od-main.go      2023-10-14 03:57:03.000000000 
+0200
@@ -105,13 +105,13 @@
                sourceURLs: []string{inFile},
                targetURL:  outFile,
        }
-       odType, _, err := guessCopyURLType(ctx, opts)
+       copyURLsContent, err := guessCopyURLType(ctx, opts)
        fatalIf(err, "Unable to guess copy URL type")
 
        // Get content of inFile, set up URLs.
-       switch odType {
+       switch copyURLsContent.copyType {
        case copyURLsTypeA:
-               odURLs = prepareOdUrls(ctx, inFile, "", outFile)
+               odURLs = makeCopyContentTypeA(*copyURLsContent)
        case copyURLsTypeB:
                return URLs{}, fmt.Errorf("invalid source path %s, destination 
cannot be a directory", outFile)
        default:
@@ -121,25 +121,6 @@
        return odURLs, nil
 }
 
-func prepareOdUrls(ctx context.Context, sourceURL, sourceVersion, targetURL 
string) URLs {
-       // Extract alias before fiddling with the clientURL.
-       sourceAlias, _, _ := mustExpandAlias(sourceURL)
-       // Find alias and expanded clientURL.
-       targetAlias, targetURL, _ := mustExpandAlias(targetURL)
-
-       // Placeholder encryption key database
-       var encKeyDB map[string][]prefixSSEPair
-
-       _, sourceContent, err := url2Stat(ctx, sourceURL, sourceVersion, false, 
encKeyDB, time.Time{}, false)
-       if err != nil {
-               // Source does not exist or insufficient privileges.
-               return URLs{Error: err}
-       }
-
-       // All OK.. We can proceed. Type A
-       return makeCopyContentTypeA(sourceAlias, sourceContent, targetAlias, 
targetURL)
-}
-
 // odCheckType checks if request is a download or upload and calls the 
appropriate function
 func odCheckType(ctx context.Context, odURLs URLs, args argKVS) (message, 
error) {
        if odURLs.SourceAlias != "" && odURLs.TargetAlias == "" {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/rm-main.go 
new/mc-20231014T015703Z/cmd/rm-main.go
--- old/mc-20231004T065256Z/cmd/rm-main.go      2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/rm-main.go      2023-10-14 03:57:03.000000000 
+0200
@@ -253,7 +253,7 @@
                // Note: UNC path using / works properly in go 1.9.2 even 
though it breaks the UNC specification.
                url = filepath.ToSlash(filepath.Clean(url))
                // namespace removal applies only for non FS. So filter out if 
passed url represents a directory
-               dir := isAliasURLDir(ctx, url, encKeyDB, time.Time{})
+               dir, _ := isAliasURLDir(ctx, url, encKeyDB, time.Time{})
                if dir {
                        _, path := url2Alias(url)
                        isNamespaceRemoval = (path == "")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/support-top-api.go 
new/mc-20231014T015703Z/cmd/support-top-api.go
--- old/mc-20231004T065256Z/cmd/support-top-api.go      2023-10-04 
08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/cmd/support-top-api.go      2023-10-14 
03:57:03.000000000 +0200
@@ -109,7 +109,7 @@
                        if apiCallInfo.Err != nil {
                                fatalIf(probe.NewError(apiCallInfo.Err), 
"Unable to fetch top API events")
                        }
-                       if matchTrace(mopts, apiCallInfo) {
+                       if mopts.matches(apiCallInfo) {
                                p.Send(topAPIResult{
                                        apiCallInfo: apiCallInfo,
                                })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/typed-errors.go 
new/mc-20231014T015703Z/cmd/typed-errors.go
--- old/mc-20231004T065256Z/cmd/typed-errors.go 2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/typed-errors.go 2023-10-14 03:57:03.000000000 
+0200
@@ -39,6 +39,13 @@
        return probe.NewError(invalidArgumentErr(errors.New(msg))).Untrace()
 }
 
+type unableToGuessErr error
+
+var errUnableToGuess = func() *probe.Error {
+       msg := "Unable to guess the type of copy operation."
+       return probe.NewError(unableToGuessErr(errors.New(msg)))
+}
+
 type unrecognizedDiffTypeErr error
 
 var errUnrecognizedDiffType = func(diff differType) *probe.Error {
@@ -97,6 +104,20 @@
        return probe.NewError(invalidTargetErr(errors.New(msg))).Untrace()
 }
 
+type requiresRecuriveErr error
+
+var errRequiresRecursive = func(URL string) *probe.Error {
+       msg := "To copy or move '" + URL + "' the --recursive flag is required."
+       return probe.NewError(requiresRecuriveErr(errors.New(msg))).Untrace()
+}
+
+type copyIntoSelfErr error
+
+var errCopyIntoSelf = func(URL string) *probe.Error {
+       msg := "Copying or moving '" + URL + "' into itself is not allowed."
+       return probe.NewError(copyIntoSelfErr(errors.New(msg))).Untrace()
+}
+
 type targetNotFoundErr error
 
 var errTargetNotFound = func(URL string) *probe.Error {
@@ -113,6 +134,13 @@
        return probe.NewError(overwriteNotAllowedErr{errors.New(msg)})
 }
 
+type targetIsNotDirErr error
+
+var errTargetIsNotDir = func(URL string) *probe.Error {
+       msg := "Target `" + URL + "` is not a folder."
+       return probe.NewError(targetIsNotDirErr(errors.New(msg))).Untrace()
+}
+
 type sourceIsDirErr error
 
 var errSourceIsDir = func(URL string) *probe.Error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/cmd/utils.go 
new/mc-20231014T015703Z/cmd/utils.go
--- old/mc-20231004T065256Z/cmd/utils.go        2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/cmd/utils.go        2023-10-14 03:57:03.000000000 
+0200
@@ -435,7 +435,8 @@
                        }).DialContext,
                        Proxy: ieproxy.GetProxyFunc(),
                        TLSClientConfig: &tls.Config{
-                               RootCAs: globalRootCAs,
+                               RootCAs:            globalRootCAs,
+                               InsecureSkipVerify: globalInsecure,
                                // Can't use SSLv3 because of POODLE and BEAST
                                // Can't use TLSv1.0 because of POODLE and 
BEAST using CBC cipher
                                // Can't use TLSv1.1 because of RC4 cipher usage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/functional-tests.sh 
new/mc-20231014T015703Z/functional-tests.sh
--- old/mc-20231004T065256Z/functional-tests.sh 2023-10-04 08:52:56.000000000 
+0200
+++ new/mc-20231014T015703Z/functional-tests.sh 2023-10-14 03:57:03.000000000 
+0200
@@ -315,6 +315,16 @@
     log_success "$start_time" "${FUNCNAME[0]}"
 }
 
+function test_od_object() {
+    show "${FUNCNAME[0]}"
+
+    start_time=$(get_time)
+    object_name="mc-test-object-$RANDOM"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd od if="${FILE_1_MB}" 
of="${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd od of="${FILE_1_MB}" 
if="${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}"
+
+    log_success "$start_time" "${FUNCNAME[0]}"
+}
 
 function test_put_object()
 {
@@ -983,6 +993,8 @@
     # create a user
     username=foo
     password=foobar12345
+    test_alias="aliasx"
+
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user add 
"$SERVER_ALIAS" "$username" "$password"
 
     # check that user appears in the user list
@@ -993,49 +1005,60 @@
     # setup temporary alias to make requests as the created user.
     scheme="https"
     if [ "$ENABLE_HTTPS" != "1" ]; then
-       scheme="http"
+         scheme="http"
     fi
     object1_name="mc-test-object-$RANDOM"
     object2_name="mc-test-object-$RANDOM"
-    export MC_HOST_foo="${scheme}://${username}:${password}@${SERVER_ENDPOINT}"
+
+    # Adding an alias for the $test_alias
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd alias set $test_alias 
"${scheme}://${SERVER_ENDPOINT}" ${username} ${password} 
+
+    # check that alias appears in the alias list
+    "${MC_CMD[@]}" --json alias list | jq -r '.alias' | grep --quiet 
"^${test_alias}$"
+    rv=$?
+    assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure ${rv} "alias 
${test_alias} did NOT appear in the list of aliases returned by server"
 
     # check that the user can write objects with readwrite policy
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy attach 
"$SERVER_ALIAS" readwrite --user="${username}"
-    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"foo/${BUCKET_NAME}/${object1_name}"
+
+    # Validate that the correct policy has been added to the user
+    "${MC_CMD[@]}" --json admin user list "${SERVER_ALIAS}" | jq -r 
'.policyName' | grep --quiet "^readwrite$"
+    rv=$?
+    assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure ${rv} "user 
${username} did NOT have the readwrite policy attached"
+
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that the user cannot write objects with readonly policy
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy detach 
"$SERVER_ALIAS" readwrite --user="${username}"
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy attach 
"$SERVER_ALIAS" readonly --user="${username}"
-    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"foo/${BUCKET_NAME}/${object2_name}"
+    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"${test_alias}/${BUCKET_NAME}/${object2_name}"
 
     # check that the user can read with readonly policy
-    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"foo/${BUCKET_NAME}/${object1_name}"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that user can delete with readwrite policy
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy attach 
"$SERVER_ALIAS" readwrite --user="${username}"
-    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm 
"foo/${BUCKET_NAME}/${object1_name}"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that user cannot perform admin actions with readwrite policy
-    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd admin info "foo"
+    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd admin info $test_alias
 
     # create object1_name for subsequent tests.
-    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"foo/${BUCKET_NAME}/${object1_name}"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that user can be disabled
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user disable 
"$SERVER_ALIAS" "$username"
 
     # check that disabled cannot perform any action
-    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"foo/${BUCKET_NAME}/${object1_name}"
+    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that user can be enabled and can then perform an allowed action
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user enable 
"$SERVER_ALIAS" "$username"
-    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"foo/${BUCKET_NAME}/${object1_name}"
+    assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     # check that user can be removed, and then is no longer available
     assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user remove 
"$SERVER_ALIAS" "$username"
-    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"foo/${BUCKET_NAME}/${object1_name}"
-
-    unset MC_HOST_foo
+    assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat 
"${test_alias}/${BUCKET_NAME}/${object1_name}"
 
     log_success "$start_time" "${FUNCNAME[0]}"
 }
@@ -1057,6 +1080,7 @@
     test_put_object_multipart
     test_get_object
     test_get_object_multipart
+    test_od_object
     test_mv_object
     test_presigned_post_policy_error
     test_presigned_put_object
@@ -1162,8 +1186,20 @@
     set +e
 }
 
+function validate_dependencies() {
+       jqVersion=$(jq --version)
+       if [[ $jqVersion == *"jq"* ]]; then
+               echo "Dependency validation complete"
+       else
+               echo "jq is missing, please install: 'sudo apt install jq'"
+               exit 1
+       fi
+}
+
 function main()
 {
+    validate_dependencies
+
     ( run_test )
     rv=$?
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/go.mod 
new/mc-20231014T015703Z/go.mod
--- old/mc-20231004T065256Z/go.mod      2023-10-04 08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/go.mod      2023-10-14 03:57:03.000000000 +0200
@@ -32,8 +32,8 @@
        github.com/rs/xid v1.5.0
        github.com/shirou/gopsutil/v3 v3.23.8
        github.com/tidwall/gjson v1.16.0
-       golang.org/x/crypto v0.13.0 // indirect
-       golang.org/x/net v0.15.0
+       golang.org/x/crypto v0.14.0 // indirect
+       golang.org/x/net v0.17.0
        golang.org/x/text v0.13.0
        gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
        gopkg.in/h2non/filetype.v1 v1.0.5
@@ -53,7 +53,7 @@
        github.com/olekukonko/tablewriter v0.0.5
        github.com/prometheus/client_model v0.4.0
        github.com/rivo/tview v0.0.0-20230909130259-ba6a2a345459
-       golang.org/x/term v0.12.0
+       golang.org/x/term v0.13.0
 )
 
 require (
@@ -120,7 +120,7 @@
        go.uber.org/multierr v1.11.0 // indirect
        go.uber.org/zap v1.25.0 // indirect
        golang.org/x/sync v0.3.0 // indirect
-       golang.org/x/sys v0.12.0
+       golang.org/x/sys v0.13.0
        google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // 
indirect
        google.golang.org/grpc v1.58.0 // indirect
        google.golang.org/protobuf v1.31.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mc-20231004T065256Z/go.sum 
new/mc-20231014T015703Z/go.sum
--- old/mc-20231004T065256Z/go.sum      2023-10-04 08:52:56.000000000 +0200
+++ new/mc-20231014T015703Z/go.sum      2023-10-14 03:57:03.000000000 +0200
@@ -267,8 +267,8 @@
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod 
h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.9.0/go.mod 
h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
-golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
-golang.org/x/crypto v0.13.0/go.mod 
h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod 
h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod 
h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -284,8 +284,8 @@
 golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -318,16 +318,16 @@
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod 
h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
-golang.org/x/term v0.12.0/go.mod 
h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
+golang.org/x/term v0.13.0/go.mod 
h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

++++++ mc.obsinfo ++++++
--- /var/tmp/diff_new_pack.TpbW7H/_old  2023-10-16 23:01:29.022051731 +0200
+++ /var/tmp/diff_new_pack.TpbW7H/_new  2023-10-16 23:01:29.026051875 +0200
@@ -1,5 +1,5 @@
 name: mc
-version: 20231004T065256Z
-mtime: 1696402376
-commit: eca8310ac822cf0e533c6bd3fb85c8d6099d1465
+version: 20231014T015703Z
+mtime: 1697248623
+commit: d158b9a478a6a5a74795f01097d069be82edfff6
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/minio-client/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.minio-client.new.20540/vendor.tar.gz differ: char 
5, line 1

Reply via email to