Example #1
0
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
}
Example #2
0
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
}
Example #3
0
// 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
}
Example #4
0
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
}
Example #5
0
// 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
}
Example #6
0
// 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
}
Example #7
0
// 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
}
Example #8
0
// 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
}
Example #9
0
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)}
}
Example #10
0
// 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))
}
Example #11
0
// 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)
}
Example #12
0
// 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"}
}
Example #13
0
func Error(cookie Magic_t) string {
	s := (C.magic_error((C.magic_t)(cookie)))
	return C.GoString(s)
}