// errorIf synonymous with fatalIf but doesn't exit on error != nil func errorIf(err *probe.Error, msg string) { if err == nil { return } if globalJSONFlag { errorMessage := ErrorMessage{ Message: msg, Type: "error", Cause: err.ToGoError(), SysInfo: err.SysInfo, } if globalDebugFlag { errorMessage.CallTrace = err.CallTrace } json, err := json.Marshal(struct { Error ErrorMessage `json:"error"` }{ Error: errorMessage, }) if err != nil { console.Fatalln(probe.NewError(err)) } console.Println(string(json)) return } if !globalDebugFlag { console.Errorln(fmt.Sprintf("%s %s", msg, err.ToGoError())) return } console.Errorln(fmt.Sprintf("%s %s", msg, err)) }
// newClientFromAlias gives a new client interface for matching // alias entry in the mc config file. If no matching host config entry // is found, fs client is returned. func newClientFromAlias(alias string, urlStr string) (Client, *probe.Error) { hostCfg := mustGetHostConfig(alias) if hostCfg == nil { // No matching host config. So we treat it like a // filesystem. fsClient, err := fsNew(urlStr) if err != nil { return nil, err.Trace(alias, urlStr) } return fsClient, nil } // We have a valid alias and hostConfig. We populate the // credentials from the match found in the config file. s3Config := new(Config) // secretKey retrieved from the environement overrides the one // present in the config file keysPairEnv := os.Getenv("MC_SECRET_" + alias) keysPairArray := strings.Split(keysPairEnv, ":") var accessKeyEnv, secretKeyEnv string if len(keysPairArray) >= 1 { accessKeyEnv = keysPairArray[0] } if len(keysPairArray) >= 2 { secretKeyEnv = keysPairArray[1] } if len(keysPairEnv) > 0 && isValidAccessKey(accessKeyEnv) && isValidSecretKey(secretKeyEnv) { s3Config.AccessKey = accessKeyEnv s3Config.SecretKey = secretKeyEnv } else { if len(keysPairEnv) > 0 { console.Errorln("Access/Secret keys associated to `" + alias + "' " + "are found in your environment but not suitable for use. " + "Falling back to the standard config.") } s3Config.AccessKey = hostCfg.AccessKey s3Config.SecretKey = hostCfg.SecretKey } s3Config.Signature = hostCfg.API s3Config.AppName = "mc" s3Config.AppVersion = Version s3Config.AppComments = []string{os.Args[0], runtime.GOOS, runtime.GOARCH} s3Config.HostURL = urlStr s3Config.Debug = globalDebug s3Config.Insecure = globalInsecure s3Client, err := s3New(s3Config) if err != nil { return nil, err.Trace(alias, urlStr) } return s3Client, nil }
// doList - list all entities inside a folder func doList(clnt client.Client, recursive bool) error { var err error for contentCh := range clnt.List(recursive) { if contentCh.Err != nil { switch err := iodine.ToError(contentCh.Err).(type) { // handle this specifically for filesystem case client.ISBrokenSymlink: console.Errorln(NewIodine(iodine.New(err, nil)).Error()) continue } if os.IsNotExist(iodine.ToError(contentCh.Err)) || os.IsPermission(iodine.ToError(contentCh.Err)) { console.Errorln(NewIodine(iodine.New(contentCh.Err, nil)).Error()) continue } err = contentCh.Err break } console.Print(parseContent(contentCh.Content)) } if err != nil { return NewIodine(iodine.New(err, map[string]string{"Target": clnt.URL().String()})) } return nil }
// errorIf synonymous with fatalIf but doesn't exit on error != nil func errorIf(err *probe.Error, msg string) { if err == nil { return } if globalJSON { errorMsg := errorMessage{ Message: msg, Type: "error", Cause: causeMessage{ Message: err.ToGoError().Error(), Error: err.ToGoError(), }, SysInfo: err.SysInfo, } if globalDebug { errorMsg.CallTrace = err.CallTrace } json, err := json.Marshal(struct { Status string `json:"status"` Error errorMessage `json:"error"` }{ Status: "error", Error: errorMsg, }) if err != nil { console.Fatalln(probe.NewError(err)) } console.Println(string(json)) return } if !globalDebug { console.Errorln(fmt.Sprintf("%s %s", msg, err.ToGoError())) return } console.Errorln(fmt.Sprintf("%s %s", msg, err)) }
func checkGolangVersion() { v1, err := version.NewVersion(strings.TrimPrefix(runtime.Version(), "go")) if err != nil { console.Fatalf("Unable to parse runtime version, %s\n", NewIodine(iodine.New(err, nil))) } switch runtime.GOOS { case "windows": v2, err := version.NewVersion(minWindowsGolangVersion) if err != nil { console.Fatalf("Unable to parse minimum version, %s\n", NewIodine(iodine.New(err, nil))) } if v1.LessThan(v2) { console.Errorln("Minimum Golang runtime expected on windows is go1.5, please compile ‘mc’ with go1.5") } default: v2, err := version.NewVersion(minGolangVersion) if err != nil { console.Fatalf("Unable to parse minimum version, %s\n", NewIodine(iodine.New(err, nil))) } if v1.LessThan(v2) { console.Errorln("Minimum Golang runtime expected on windows is go1.3, please compile ‘mc’ with go1.3") } } }
// doPrepareCopyURLs scans the source URL and prepares a list of objects for copying. func doPrepareCopyURLs(session *sessionV2, trapCh <-chan bool) { // Separate source and target. 'cp' can take only one target, // but any number of sources, even the recursive URLs mixed in-between. sourceURLs := session.Header.CommandArgs[:len(session.Header.CommandArgs)-1] targetURL := session.Header.CommandArgs[len(session.Header.CommandArgs)-1] // Last one is target var totalBytes int64 var totalObjects int // Create a session data file to store the processed URLs. dataFP := session.NewDataWriter() scanBar := scanBarFactory(strings.Join(sourceURLs, " ")) URLsCh := prepareCopyURLs(sourceURLs, targetURL) done := false for done == false { select { case cpURLs, ok := <-URLsCh: if !ok { // Done with URL prepration done = true break } if cpURLs.Error != nil { console.Errorln(cpURLs.Error) break } jsonData, err := json.Marshal(cpURLs) if err != nil { session.Close() console.Fatalf("Unable to marshal URLs to JSON. %s\n", err) } fmt.Fprintln(dataFP, string(jsonData)) scanBar(cpURLs.SourceContent.Name) totalBytes += cpURLs.SourceContent.Size totalObjects++ case <-trapCh: session.Close() // If we are interrupted during the URL scanning, we drop the session. session.Delete() os.Exit(0) } } session.Header.TotalBytes = totalBytes session.Header.TotalObjects = totalObjects session.Save() }
// doPrepareCastURLs scans the source URL and prepares a list of objects for casting. func doPrepareCastURLs(session *sessionV2, trapCh <-chan bool) { sourceURL := session.Header.CommandArgs[0] // first one is source. targetURLs := session.Header.CommandArgs[1:] var totalBytes int64 var totalObjects int // Create a session data file to store the processed URLs. dataFP := session.NewDataWriter() scanBar := scanBarFactory(sourceURL) URLsCh := prepareCastURLs(sourceURL, targetURLs) done := false for done == false { select { case sURLs, ok := <-URLsCh: if !ok { // Done with URL prepration done = true break } if sURLs.Error != nil { console.Errorln(sURLs.Error) break } jsonData, err := json.Marshal(sURLs) if err != nil { session.Close() console.Fatalf("Unable to marshal URLs to JSON. %s\n", err) } fmt.Fprintln(dataFP, string(jsonData)) scanBar(sURLs.SourceContent.Name) totalBytes += sURLs.SourceContent.Size totalObjects++ case <-trapCh: session.Close() // If we are interrupted during the URL scanning, we drop the session. session.Delete() os.Exit(0) } } session.Header.TotalBytes = totalBytes session.Header.TotalObjects = totalObjects session.Save() }
// doCopy - Copy a singe file from source to destination func doCopy(cpURLs copyURLs, bar *barSend, cpQueue chan bool, wg *sync.WaitGroup) error { defer wg.Done() // Notify that this copy routine is done. defer func() { <-cpQueue }() if !globalQuietFlag || !globalJSONFlag { bar.SetCaption(cpURLs.SourceContent.Name + ": ") } reader, length, err := getSource(cpURLs.SourceContent.Name) if err != nil { if !globalQuietFlag || !globalJSONFlag { bar.ErrorGet(length) } return NewIodine(iodine.New(err, map[string]string{"URL": cpURLs.SourceContent.Name})) } var newReader io.ReadCloser if globalQuietFlag || globalJSONFlag { console.PrintC(CopyMessage{ Source: cpURLs.SourceContent.Name, Target: cpURLs.TargetContent.Name, Length: cpURLs.SourceContent.Size, }) newReader = reader } else { // set up progress newReader = bar.NewProxyReader(reader) } defer newReader.Close() err = putTarget(cpURLs.TargetContent.Name, length, newReader) if err != nil { if !globalQuietFlag || !globalJSONFlag { bar.ErrorPut(length) } console.Println("") console.Errorln(NewIodine(err)) } return nil }