func getPermissionsAsString(driveFile *gdrive.File) (string, error) { var str string if driveFile.IsFolder() { str = "d" } else { str = "-" } perm, err := getPermissions(driveFile) if err != nil { // No permissions are available if the file was uploaded via the // Drive Web page, for example. str += "?????????" } else { rwx := "rwx" for i := 0; i < 9; i++ { if perm&(1<<(8-uint(i))) != 0 { str += string(rwx[i%3]) } else { str += "-" } } } return str, nil }
// If we didn't shut down cleanly before, there may be files that // don't have the various properties we expect. Check for that now // and patch things up as needed. func createMissingProperties(f *gdrive.File, mode os.FileMode, encrypt bool) error { if !f.IsFolder() && encrypt { if _, err := f.GetProperty("IV"); err != nil { if f.FileSize == 0 { // Compute a unique IV for the file. iv := getRandomBytes(aes.BlockSize) ivhex := hex.EncodeToString(iv) debug.Printf("Creating IV property for file %s, "+ "which doesn't have one.", f.Path) err := gd.AddProperty("IV", ivhex, f) if err != nil { return err } } else { // This is state of affairs really shouldn't ever happen, but // if somehow it does, it's important that we catch it: the // file is missing the IV property, but has some // contents. Presumably the IV is at the start of the file // contents and we could initialize the property from that // here, but any successfully created file should already have // the property, so we'll just error out, since it's not clear // what's going on here... return fmt.Errorf("encrypted file on Drive is missing" + "IV property, but has non-zero length. Can't create the IV " + "property without examining file contents.") } } } if _, err := f.GetProperty("Permissions"); err != nil { debug.Printf("Creating Permissions property for file %s, "+ "which doesn't have one.", f.Path) err := gd.AddProperty("Permissions", fmt.Sprintf("%#o", mode&os.ModePerm), f) if err != nil { return err } } return nil }
// Produce listing output to stdout for a single file. func lsFile(f *gdrive.File, recursive, long, longlong bool) { printFilename := f.Path if !recursive { printFilename = filepath.Base(printFilename) } if f.IsFolder() { printFilename += string(os.PathSeparator) } if !long && !longlong { fmt.Printf("%s\n", printFilename) return } synctime := f.ModTime permString, _ := getPermissionsAsString(f) if longlong { md5 := f.Md5 if len(md5) != 32 { md5 = "--------------------------------" } fmt.Printf("%s %s %s %s %s\n", permString, fmtbytes(f.FileSize, true), md5, synctime.Format(time.ANSIC), printFilename) if debug { fmt.Printf("\t[ ") for _, prop := range f.Properties { fmt.Printf("%s: %s, ", prop.Key, prop.Value) } fmt.Printf("MimeType: %s, ", f.MimeType) fmt.Printf("id: %s ]\n", f.Id) } } else { fmt.Printf("%s %s %s %s\n", permString, fmtbytes(f.FileSize, true), synctime.Format(time.ANSIC), printFilename) } }