如何删除dev_appserver的源缓存?

时间:2018-10-27 05:15:39

标签: google-app-engine go system-calls

我正在使用github.com/pkg/sftp中的sftp代码作为起点,以使google app引擎成为sftp服务器,其中服务器端文件实际上是gcs。

dev_appserver在attrs.go中抱怨syscall,因此我注释掉了syscall的所有用法并删除了导入。

即使我已经确认源代码已经绝对更新为不使用syscall或导入syscall,dev_appserver仍然会抱怨syscall。
我问的是dev_appserver的源缓存,因为这是我对这种行为显示方式的唯一猜测。

错误消息     2018/10/26 23:11:32 go-app-builder:解析输入失败:解析器:github.com/pkg/sftp/attrs.go中从GOPATH导入了错误的“ syscall”

整个main.go文件:

package main
// small wrapper around sftp server that allows it to be used as a separate process subsystem call by the ssh server.
// in practice this will statically link; however this allows unit testing from the sftp client.
import (
    "flag"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "github.com/pkg/sftp"
    "google.golang.org/appengine"
    "net/http"
)

type MyWriteCloser struct {
    io.Writer
}

func (mwc *MyWriteCloser) Close() error {
    // Noop
    return nil
}

func main() {
    http.HandleFunc("/", handle)
    appengine.Main()
}

func handle(w http.ResponseWriter, r *http.Request) {
    var (
        readOnly    bool
        debugStderr bool
        debugLevel  string
        options     []sftp.ServerOption
    )

    flag.BoolVar(&readOnly, "R", false, "read-only server")
    flag.BoolVar(&debugStderr, "e", false, "debug to stderr")
    flag.StringVar(&debugLevel, "l", "none", "debug level (ignored)")
    flag.Parse()

    debugStream := ioutil.Discard
    if debugStderr {
        debugStream = os.Stderr
    }
    options = append(options, sftp.WithDebug(debugStream))

    if readOnly {
        options = append(options, sftp.ReadOnly())
    }

    mwc := &MyWriteCloser{w}

    svr, _ := sftp.NewServer(
        struct {
            io.Reader
            io.WriteCloser
        }{r.Body,
            mwc,
        },
        options...,
    )
    if err := svr.Serve(); err != nil {
        fmt.Fprintf(w, "sftp server completed with error: %v", err)
        os.Exit(1)
    }
}

整个attrs.go文件:

   package sftp

// ssh_FXP_ATTRS support
// see http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-5

import (
    "os"
    "time"
)

const (
    ssh_FILEXFER_ATTR_SIZE        = 0x00000001
    ssh_FILEXFER_ATTR_UIDGID      = 0x00000002
    ssh_FILEXFER_ATTR_PERMISSIONS = 0x00000004
    ssh_FILEXFER_ATTR_ACMODTIME   = 0x00000008
    ssh_FILEXFER_ATTR_EXTENDED    = 0x80000000
)

// fileInfo is an artificial type designed to satisfy os.FileInfo.
type fileInfo struct {
    name  string
    size  int64
    mode  os.FileMode
    mtime time.Time
    sys   interface{}
}

// Name returns the base name of the file.
func (fi *fileInfo) Name() string { return fi.name }

// Size returns the length in bytes for regular files; system-dependent for others.
func (fi *fileInfo) Size() int64 { return fi.size }

// Mode returns file mode bits.
func (fi *fileInfo) Mode() os.FileMode { return fi.mode }

// ModTime returns the last modification time of the file.
func (fi *fileInfo) ModTime() time.Time { return fi.mtime }

// IsDir returns true if the file is a directory.
func (fi *fileInfo) IsDir() bool { return fi.Mode().IsDir() }

func (fi *fileInfo) Sys() interface{} { return fi.sys }

// FileStat holds the original unmarshalled values from a call to READDIR or
// *STAT. It is exported for the purposes of accessing the raw values via
// os.FileInfo.Sys(). It is also used server side to store the unmarshalled
// values for SetStat.
type FileStat struct {
    Size     uint64
    Mode     uint32
    Mtime    uint32
    Atime    uint32
    UID      uint32
    GID      uint32
    Extended []StatExtended
}

// StatExtended contains additional, extended information for a FileStat.
type StatExtended struct {
    ExtType string
    ExtData string
}

func fileInfoFromStat(st *FileStat, name string) os.FileInfo {
    fs := &fileInfo{
        name:  name,
        size:  int64(st.Size),
        mode:  toFileMode(st.Mode),
        mtime: time.Unix(int64(st.Mtime), 0),
        sys:   st,
    }
    return fs
}

func fileStatFromInfo(fi os.FileInfo) (uint32, FileStat) {
    mtime := fi.ModTime().Unix()
    atime := mtime
    var flags uint32 = ssh_FILEXFER_ATTR_SIZE |
        ssh_FILEXFER_ATTR_PERMISSIONS |
        ssh_FILEXFER_ATTR_ACMODTIME

    fileStat := FileStat{
        Size:  uint64(fi.Size()),
        Mode:  fromFileMode(fi.Mode()),
        Mtime: uint32(mtime),
        Atime: uint32(atime),
    }

    // os specific file stat decoding
    fileStatFromInfoOs(fi, &flags, &fileStat)

    return flags, fileStat
}

func unmarshalAttrs(b []byte) (*FileStat, []byte) {
    flags, b := unmarshalUint32(b)
    return getFileStat(flags, b)
}

func getFileStat(flags uint32, b []byte) (*FileStat, []byte) {
    var fs FileStat
    if flags&ssh_FILEXFER_ATTR_SIZE == ssh_FILEXFER_ATTR_SIZE {
        fs.Size, b = unmarshalUint64(b)
    }
    if flags&ssh_FILEXFER_ATTR_UIDGID == ssh_FILEXFER_ATTR_UIDGID {
        fs.UID, b = unmarshalUint32(b)
    }
    if flags&ssh_FILEXFER_ATTR_UIDGID == ssh_FILEXFER_ATTR_UIDGID {
        fs.GID, b = unmarshalUint32(b)
    }
    if flags&ssh_FILEXFER_ATTR_PERMISSIONS == ssh_FILEXFER_ATTR_PERMISSIONS {
        fs.Mode, b = unmarshalUint32(b)
    }
    if flags&ssh_FILEXFER_ATTR_ACMODTIME == ssh_FILEXFER_ATTR_ACMODTIME {
        fs.Atime, b = unmarshalUint32(b)
        fs.Mtime, b = unmarshalUint32(b)
    }
    if flags&ssh_FILEXFER_ATTR_EXTENDED == ssh_FILEXFER_ATTR_EXTENDED {
        var count uint32
        count, b = unmarshalUint32(b)
        ext := make([]StatExtended, count)
        for i := uint32(0); i < count; i++ {
            var typ string
            var data string
            typ, b = unmarshalString(b)
            data, b = unmarshalString(b)
            ext[i] = StatExtended{typ, data}
        }
        fs.Extended = ext
    }
    return &fs, b
}

func marshalFileInfo(b []byte, fi os.FileInfo) []byte {
    // attributes variable struct, and also variable per protocol version
    // spec version 3 attributes:
    // uint32   flags
    // uint64   size           present only if flag SSH_FILEXFER_ATTR_SIZE
    // uint32   uid            present only if flag SSH_FILEXFER_ATTR_UIDGID
    // uint32   gid            present only if flag SSH_FILEXFER_ATTR_UIDGID
    // uint32   permissions    present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
    // uint32   atime          present only if flag SSH_FILEXFER_ACMODTIME
    // uint32   mtime          present only if flag SSH_FILEXFER_ACMODTIME
    // uint32   extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
    // string   extended_type
    // string   extended_data
    // ...      more extended data (extended_type - extended_data pairs),
    //     so that number of pairs equals extended_count

    flags, fileStat := fileStatFromInfo(fi)

    b = marshalUint32(b, flags)
    if flags&ssh_FILEXFER_ATTR_SIZE != 0 {
        b = marshalUint64(b, fileStat.Size)
    }
    if flags&ssh_FILEXFER_ATTR_UIDGID != 0 {
        b = marshalUint32(b, fileStat.UID)
        b = marshalUint32(b, fileStat.GID)
    }
    if flags&ssh_FILEXFER_ATTR_PERMISSIONS != 0 {
        b = marshalUint32(b, fileStat.Mode)
    }
    if flags&ssh_FILEXFER_ATTR_ACMODTIME != 0 {
        b = marshalUint32(b, fileStat.Atime)
        b = marshalUint32(b, fileStat.Mtime)
    }

    return b
}

// toFileMode converts sftp filemode bits to the os.FileMode specification
func toFileMode(mode uint32) os.FileMode {
    var fm = os.FileMode(mode & 0777)
    //switch mode & syscall.S_IFMT {
    //case syscall.S_IFBLK:
    //  fm |= os.ModeDevice
    //case syscall.S_IFCHR:
    //  fm |= os.ModeDevice | os.ModeCharDevice
    //case syscall.S_IFDIR:
    //  fm |= os.ModeDir
    //case syscall.S_IFIFO:
    //  fm |= os.ModeNamedPipe
    //case syscall.S_IFLNK:
    //  fm |= os.ModeSymlink
    //case syscall.S_IFREG:
    //  // nothing to do
    //case syscall.S_IFSOCK:
    //  fm |= os.ModeSocket
    //}
    //if mode&syscall.S_ISGID != 0 {
    //  fm |= os.ModeSetgid
    //}
    //if mode&syscall.S_ISUID != 0 {
    //  fm |= os.ModeSetuid
    //}
    //if mode&syscall.S_ISVTX != 0 {
    //  fm |= os.ModeSticky
    //}
    return fm
}

// fromFileMode converts from the os.FileMode specification to sftp filemode bits
func fromFileMode(mode os.FileMode) uint32 {
    ret := uint32(0)

    //if mode&os.ModeDevice != 0 {
    //  if mode&os.ModeCharDevice != 0 {
    //      ret |= syscall.S_IFCHR
    //  } else {
    //      ret |= syscall.S_IFBLK
    //  }
    //}
    //if mode&os.ModeDir != 0 {
    //  ret |= syscall.S_IFDIR
    //}
    //if mode&os.ModeSymlink != 0 {
    //  ret |= syscall.S_IFLNK
    //}
    //if mode&os.ModeNamedPipe != 0 {
    //  ret |= syscall.S_IFIFO
    //}
    //if mode&os.ModeSetgid != 0 {
    //  ret |= syscall.S_ISGID
    //}
    //if mode&os.ModeSetuid != 0 {
    //  ret |= syscall.S_ISUID
    //}
    //if mode&os.ModeSticky != 0 {
    //  ret |= syscall.S_ISVTX
    //}
    //if mode&os.ModeSocket != 0 {
    //  ret |= syscall.S_IFSOCK
    //}
    //
    //if mode&os.ModeType == 0 {
    //  ret |= syscall.S_IFREG
    //}
    //ret |= uint32(mode & os.ModePerm)

    return ret
}

0 个答案:

没有答案