// list the objects into the function supplied
//
// dir is the starting directory, "" for root
//
// Set recurse to read sub directories
list the objects into the function supplied

dir is the starting directory, "" for root

Set recurse to read sub directories
// list the objects into the function supplied // // dir is the starting directory " " for root // // Set recurse to read sub directories
func (f *Fs) list(dir string, recurse bool, fn listFn) error {
	root := f.root
	if dir != "" {
		root += dir + "/"
	}
	maxKeys := int64(listChunkSize)
	delimiter := ""
	if !recurse {
		delimiter = "/"
	}
	var marker *string
	for {
		req := s3.ListObjectsInput{
			Bucket:    &f.bucket,
			Delimiter: &delimiter,
			Prefix:    &root,
			MaxKeys:   &maxKeys,
			Marker:    marker,
		}
		resp, err := f.c.ListObjects(&req)
		if err != nil {
			if awsErr, ok := err.(awserr.RequestFailure); ok {
				if awsErr.StatusCode() == http.StatusNotFound {
					err = fs.ErrorDirNotFound
				}
			}
			return err
		}
		rootLength := len(f.root)
		if !recurse {
			for _, commonPrefix := range resp.CommonPrefixes {
				if commonPrefix.Prefix == nil {
					fs.Logf(f, "Nil common prefix received")
					continue
				}
				remote := *commonPrefix.Prefix
				if !strings.HasPrefix(remote, f.root) {
					fs.Logf(f, "Odd name received %q", remote)
					continue
				}
				remote = remote[rootLength:]
				if strings.HasSuffix(remote, "/") {
					remote = remote[:len(remote)-1]
				}
				err = fn(remote, &s3.Object{Key: &remote}, true)
				if err != nil {
					return err
				}
			}
		}
		for _, object := range resp.Contents {
			key := aws.StringValue(object.Key)
			if !strings.HasPrefix(key, f.root) {
				fs.Logf(f, "Odd name received %q", key)
				continue
			}
			remote := key[rootLength:]
			if (strings.HasSuffix(remote, "/") || remote == "") && *object.Size == 0 {
				if recurse && remote != "" {
					remote = remote[:len(remote)-1]
					err = fn(remote, &s3.Object{Key: &remote}, true)
					if err != nil {
						return err
					}
				}
				continue 
			}
			err = fn(remote, object, false)
			if err != nil {
				return err
			}
		}
		if !aws.BoolValue(resp.IsTruncated) {
			break
		}
		if resp.NextMarker == nil || *resp.NextMarker == "" {
			if len(resp.Contents) == 0 {
				return errors.New("s3 protocol error: received listing with IsTruncated set, no NextMarker and no Contents")
			}
			marker = resp.Contents[len(resp.Contents)-1].Key
		} else {
			marker = resp.NextMarker
		}
	}
	return nil
}
func ( f * Fs ) list ( dir string , recurse bool , fn listFn ) error { root := f . root if dir != " " { root += dir + " " } maxKeys := int64 ( listChunkSize ) delimiter := " " if ! recurse { delimiter = " " } var marker * string for { req := s3 . ListObjectsInput { Bucket : & f . bucket , Delimiter : & delimiter , Prefix : & root , MaxKeys : & maxKeys , Marker : marker , } resp , err := f . c . ListObjects ( & req ) if err != nil { if awsErr , ok := err . ( awserr . RequestFailure ) ; ok { if awsErr . StatusCode ( ) == http . StatusNotFound { err = fs . ErrorDirNotFound } } return err } rootLength := len ( f . root ) if ! recurse { for _ , commonPrefix := range resp . CommonPrefixes { if commonPrefix . Prefix == nil { fs . Logf ( f , " " ) continue } remote := * commonPrefix . Prefix if ! strings . HasPrefix ( remote , f . root ) { fs . Logf ( f , " " , remote ) continue } remote = remote [ rootLength : ] if strings . HasSuffix ( remote , " " ) { remote = remote [ : len ( remote ) - 1 ] } err = fn ( remote , & s3 . Object { Key : & remote } , true ) if err != nil { return err } } } for _ , object := range resp . Contents { key := aws . StringValue ( object . Key ) if ! strings . HasPrefix ( key , f . root ) { fs . Logf ( f , " " , key ) continue } remote := key [ rootLength : ] if ( strings . HasSuffix ( remote , " " ) || remote == " " ) && * object . Size == 0 { if recurse && remote != " " { remote = remote [ : len ( remote ) - 1 ] err = fn ( remote , & s3 . Object { Key : & remote } , true ) if err != nil { return err } } continue } err = fn ( remote , object , false ) if err != nil { return err } } if ! aws . BoolValue ( resp . IsTruncated ) { break } if resp . NextMarker == nil || * resp . NextMarker == " " { if len ( resp . Contents ) == 0 { return errors . New ( " " ) } marker = resp . Contents [ len ( resp . Contents ) - 1 ] . Key } else { marker = resp . NextMarker } } return nil }
list the objects into the function supplied
list the objects into the function supplied
// FIXME need to implement ALL loop // is this a directory marker? // add a directory in if --fast-list since will have no prefixes // skip directory marker // Use NextMarker if set, otherwise use last Key