func New(flags MagicFlag) (*Magic, error) { db := C.magic_open(C.int(0)) if db == nil { return nil, errors.New("Error allocating magic cookie") } if code := C.magic_setflags(db, C.int(flags)); code != 0 { return nil, errors.New(C.GoString(C.magic_error(db))) } if code := C.magic_load(db, nil); code != 0 { return nil, errors.New(C.GoString(C.magic_error(db))) } return &Magic{db}, nil }
func Open(flags MagicFlag) error { db = C.magic_open(C.int(0)) if db == nil { return errors.New("error opening magic") } if code := C.magic_setflags(db, C.int(flags)); code != 0 { return errors.New(C.GoString(C.magic_error(db))) } if code := C.magic_load(db, nil); code != 0 { return errors.New(C.GoString(C.magic_error(db))) } return nil }
// TypeByBuffer looks up for a blob's mimetype by its contents. // It uses a magic number database which is described in magic(5). func (m *Magic) TypeByBuffer(blob []byte) (string, error) { bytes := unsafe.Pointer(&blob[0]) out := C.magic_buffer(m.db, bytes, C.size_t(len(blob))) if out == nil { return "", errors.New(C.GoString(C.magic_error(m.db))) } return C.GoString(out), nil }
func New() (*Magic, error) { db := C.magic_open(C.int(0)) C.magic_setflags(db, C.int(C.MAGIC_SYMLINK|C.MAGIC_ERROR)) if code := C.magic_load(db, nil); code != 0 { return nil, errors.New(C.GoString(C.magic_error(db))) } return &Magic{db}, nil }
// NewDecoder creates a detector that uses libmagic. It initializes // the opens the magicmime database with the specified flags. Upon // success users are expected to call Close on the returned Decoder // when it is no longer needed. func NewDecoder(flags Flag) (*Decoder, error) { db := C.magic_open(C.int(0)) if db == nil { return nil, errors.New("error opening magic") } d := &Decoder{db: db} if code := C.magic_setflags(db, C.int(flags)); code != 0 { d.Close() return nil, errors.New(C.GoString(C.magic_error(d.db))) } if code := C.magic_load(db, nil); code != 0 { d.Close() return nil, errors.New(C.GoString(C.magic_error(d.db))) } return d, nil }
// TypeByFile looks up for a file's mimetype by its content. // It uses a magic number database which is described in magic(5). func (m *Magic) TypeByFile(filePath string) (string, error) { path := C.CString(filePath) defer C.free(unsafe.Pointer(path)) out := C.magic_file(m.db, path) if out == nil { return "", errors.New(C.GoString(C.magic_error(m.db))) } return C.GoString(out), nil }
// TypeByFile looks up for a file's mimetype by its content. // It uses a magic number database which is described in magic(5). func (d *Decoder) TypeByFile(filename string) (string, error) { path := C.CString(filename) defer C.free(unsafe.Pointer(path)) out := C.magic_file(d.db, path) if out == nil { return "", errors.New(C.GoString(C.magic_error(d.db))) } return C.GoString(out), nil }
// File // // If there is an error, it will be of type *Error. func (mgc *Magic) File(filename string) (string, error) { mgc.Lock() defer mgc.Unlock() runtime.KeepAlive(mgc.magic) if mgc.cookie == nil { return "", mgc.error() } cfilename := C.CString(filename) runtime.KeepAlive(cfilename) defer C.free(unsafe.Pointer(cfilename)) cstring := C.magic_file_wrapper(mgc.cookie, cfilename, C.int(mgc.flags)) if cstring == nil { rv, err := Version() if err != nil && err.(*Error).Errno != int(syscall.ENOSYS) { return "", err } // Handle the case when the "ERROR" flag is set regardless // of the current version of the underlying Magic library. // // Prior to version 5.15 the correct behaviour that concerns // the following IEEE 1003.1 standards was broken: // // http://pubs.opengroup.org/onlinepubs/007904975/utilities/file.html // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html // // This is an attempt to mitigate the problem and correct // it to achieve the desired behaviour as per the standards. if mgc.flags&ERROR != 0 { return "", mgc.error() } else if rv < 515 { C.magic_errno(mgc.cookie) cstring = C.magic_error(mgc.cookie) } } // XXX(kwilczynski): This case should not happen, ever. if cstring == nil { return "", &Error{-1, "unknown result or nil pointer"} } // Depending on the version of the underlying // Magic library the magic_file() function can // fail and either yield no results or return // the "(null)" string instead. Often this // would indicate that an older version of // the Magic library is in use. s := C.GoString(cstring) if s == "" || s == "(null)" { return "", &Error{-1, "empty or invalid result"} } return s, nil }
func magicError(magic C.magic_t) error { errorStr, err := C.magic_error(magic) if err != nil { // hope it unreachable! panic("unreachable") } if errorStr == nil { return nil } return &MagicError{C.GoString(errorStr)} }
// check checks libmagic for any pending errors. func (m *Magic) check() error { if m.ptr == nil { return ConnectionError } cr := C.magic_error(m.ptr) if cr == nil { return nil } return errors.New(C.GoString(cr)) }
// check checks libmagic for any pending errors. func (m *Magic) check() error { if m.ptr == nil { return ConnectionError } cr := C.magic_error(m.ptr) if cr == nil { return nil } r := C.GoString(cr) C.free(unsafe.Pointer(cr)) return errors.New(r) }
// error retrieves an error from the underlying Magic library. func (mgc *Magic) error() *Error { if mgc.cookie == nil { errno := syscall.EFAULT return &Error{int(errno), "Magic library is not open"} } runtime.KeepAlive(mgc.magic) cstring := C.magic_error(mgc.cookie) if cstring != nil { // Depending on the version of the underlying // Magic library, the error reporting facilities // can fail and either yield no results or return // the "(null)" string instead. Often this would // indicate that an older version of the Magic // library is in use. s := C.GoString(cstring) if s == "" || s == "(null)" { return &Error{-1, "empty or invalid error message"} } errno := int(C.magic_errno(mgc.cookie)) return &Error{errno, s} } return &Error{-1, "unknown error"} }
func Error(cookie Magic_t) string { s := (C.magic_error((C.magic_t)(cookie))) return C.GoString(s) }