@ -0,0 +1,186 @@ | |||
# | |||
# Copyright (C) 2018 Jeffery To | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
ifeq ($(origin GO_INCLUDE_DIR),undefined) | |||
GO_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST))) | |||
endif | |||
include $(GO_INCLUDE_DIR)/golang-values.mk | |||
# $(1) valid GOOS_GOARCH combinations | |||
# $(2) go version id | |||
define GoCompiler/Default/CheckHost | |||
$(if $(filter $(GO_HOST_OS_ARCH),$(1)),,$(error go-$(2) cannot be installed on $(GO_HOST_OS)/$(GO_HOST_ARCH))) | |||
endef | |||
# $(1) source go root | |||
# $(2) destination prefix | |||
# $(3) go version id | |||
# $(4) additional environment variables (optional) | |||
define GoCompiler/Default/Make | |||
( \ | |||
cd $(1)/src ; \ | |||
$(if $(2),GOROOT_FINAL=$(2)/lib/go-$(3)) \ | |||
$(4) \ | |||
$(BASH) make.bash --no-banner ; \ | |||
) | |||
endef | |||
# $(1) destination prefix | |||
# $(2) go version id | |||
define GoCompiler/Default/Install/make-dirs | |||
$(INSTALL_DIR) $(1)/lib/go-$(2) | |||
$(INSTALL_DIR) $(1)/share/go-$(2) | |||
endef | |||
# $(1) source go root | |||
# $(2) destination prefix | |||
# $(3) go version id | |||
# $(4) file/directory name | |||
define GoCompiler/Default/Install/install-share-data | |||
$(CP) $(1)/$(4) $(2)/share/go-$(3)/ | |||
$(LN) ../../share/go-$(3)/$(4) $(2)/lib/go-$(3)/ | |||
endef | |||
# $(1) source go root | |||
# $(2) destination prefix | |||
# $(3) go version id | |||
# $(4) GOOS_GOARCH | |||
define GoCompiler/Default/Install/Bin | |||
$(call GoCompiler/Default/Install/make-dirs,$(2),$(3)) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),api) | |||
$(INSTALL_DATA) -p $(1)/VERSION $(2)/lib/go-$(3)/ | |||
for file in AUTHORS CONTRIBUTING.md CONTRIBUTORS LICENSE PATENTS README README.md; do \ | |||
if [ -f $(1)/$$$$file ]; then \ | |||
$(INSTALL_DATA) -p $(1)/$$$$file $(2)/share/go-$(3)/ ; \ | |||
fi ; \ | |||
done | |||
$(INSTALL_DIR) $(2)/lib/go-$(3)/bin | |||
ifeq ($(4),$(GO_HOST_OS_ARCH)) | |||
$(INSTALL_BIN) -p $(1)/bin/* $(2)/lib/go-$(3)/bin/ | |||
else | |||
$(INSTALL_BIN) -p $(1)/bin/$(4)/* $(2)/lib/go-$(3)/bin/ | |||
endif | |||
$(INSTALL_DIR) $(2)/lib/go-$(3)/pkg | |||
$(CP) $(1)/pkg/$(4) $(2)/lib/go-$(3)/pkg/ | |||
$(INSTALL_DIR) $(2)/lib/go-$(3)/pkg/tool/$(4) | |||
$(INSTALL_BIN) -p $(1)/pkg/tool/$(4)/* $(2)/lib/go-$(3)/pkg/tool/$(4)/ | |||
endef | |||
# $(1) destination prefix | |||
# $(2) go version id | |||
define GoCompiler/Default/Install/BinLinks | |||
$(INSTALL_DIR) $(1)/bin | |||
$(LN) ../lib/go-$(2)/bin/go $(1)/bin/go | |||
$(LN) ../lib/go-$(2)/bin/gofmt $(1)/bin/gofmt | |||
endef | |||
# $(1) source go root | |||
# $(2) destination prefix | |||
# $(3) go version id | |||
define GoCompiler/Default/Install/Doc | |||
$(call GoCompiler/Default/Install/make-dirs,$(2),$(3)) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),doc) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),favicon.ico) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),robots.txt) | |||
endef | |||
# $(1) source go root | |||
# $(2) destination prefix | |||
# $(3) go version id | |||
define GoCompiler/Default/Install/Src | |||
$(call GoCompiler/Default/Install/make-dirs,$(2),$(3)) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),lib) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),misc) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),src) | |||
$(call GoCompiler/Default/Install/install-share-data,$(1),$(2),$(3),test) | |||
$(FIND) \ | |||
$(2)/share/go-$(3)/src/ \ | |||
\! -type d -a \( -name '*.bat' -o -name '*.rc' \) \ | |||
-delete | |||
if [ -d $(1)/pkg/include ]; then \ | |||
$(INSTALL_DIR) $(2)/lib/go-$(3)/pkg ; \ | |||
$(INSTALL_DIR) $(2)/share/go-$(3)/pkg ; \ | |||
$(CP) $(1)/pkg/include $(2)/share/go-$(3)/pkg/ ; \ | |||
$(LN) ../../../share/go-$(3)/pkg/include $(2)/lib/go-$(3)/pkg/ ; \ | |||
fi | |||
endef | |||
# $(1) destination prefix | |||
# $(2) go version id | |||
define GoCompiler/Default/Uninstall | |||
rm -rf $(1)/lib/go-$(2) | |||
rm -rf $(1)/share/go-$(2) | |||
endef | |||
# $(1) destination prefix | |||
define GoCompiler/Default/Uninstall/BinLinks | |||
rm -f $(1)/bin/go | |||
rm -f $(1)/bin/gofmt | |||
endef | |||
# $(1) profile name | |||
# $(2) source go root | |||
# $(3) destination prefix | |||
# $(4) go version id | |||
# $(5) GOOS_GOARCH | |||
define GoCompiler/AddProfile | |||
# $$(1) valid GOOS_GOARCH combinations | |||
define GoCompiler/$(1)/CheckHost | |||
$$(call GoCompiler/Default/CheckHost,$$(1),$(4)) | |||
endef | |||
# $$(1) additional environment variables (optional) | |||
define GoCompiler/$(1)/Make | |||
$$(call GoCompiler/Default/Make,$(2),$(3),$(4),$$(1)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Install/Bin | |||
$$(call GoCompiler/Default/Install/Bin,$(2),$$(or $$(1),$(3)),$(4),$(5)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Install/BinLinks | |||
$$(call GoCompiler/Default/Install/BinLinks,$$(or $$(1),$(3)),$(4)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Install/Doc | |||
$$(call GoCompiler/Default/Install/Doc,$(2),$$(or $$(1),$(3)),$(4)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Install/Src | |||
$$(call GoCompiler/Default/Install/Src,$(2),$$(or $$(1),$(3)),$(4)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Uninstall | |||
$$(call GoCompiler/Default/Uninstall,$$(or $$(1),$(3)),$(4)) | |||
endef | |||
# $$(1) override install prefix (optional) | |||
define GoCompiler/$(1)/Uninstall/BinLinks | |||
$$(call GoCompiler/Default/Uninstall/BinLinks,$$(or $$(1),$(3))) | |||
endef | |||
endef |
@ -0,0 +1,297 @@ | |||
# | |||
# Copyright (C) 2018 Jeffery To | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
ifeq ($(origin GO_INCLUDE_DIR),undefined) | |||
GO_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST))) | |||
endif | |||
include $(GO_INCLUDE_DIR)/golang-values.mk | |||
# Variables (all optional, except GO_PKG) to be set in package | |||
# Makefiles: | |||
# | |||
# GO_PKG (required) - name of Go package | |||
# | |||
# Go name of the package. | |||
# | |||
# e.g. GO_PKG:=golang.org/x/text | |||
# | |||
# | |||
# GO_PKG_INSTALL_EXTRA - list of regular expressions, default empty | |||
# | |||
# Additional files/directories to install. By default, only these | |||
# files are installed: | |||
# | |||
# * Files with one of these extensions: | |||
# .go, .c, .cc, .h, .hh, .proto, .s | |||
# | |||
# * Files in any 'testdata' directory | |||
# | |||
# e.g. GO_PKG_INSTALL_EXTRA:=example.toml marshal_test.toml | |||
# | |||
# | |||
# GO_PKG_INSTALL_ALL - boolean (0 or 1), default false | |||
# | |||
# If true, install all files regardless of extension or directory. | |||
# | |||
# e.g. GO_PKG_INSTALL_ALL:=1 | |||
# | |||
# | |||
# GO_PKG_SOURCE_ONLY - boolean (0 or 1), default false | |||
# | |||
# If true, 'go install' will not be called. If the package does not | |||
# (or should not) build any binaries, then specifying this option will | |||
# save build time. | |||
# | |||
# e.g. GO_PKG_SOURCE_ONLY:=1 | |||
# | |||
# | |||
# GO_PKG_BUILD_PKG - list of build targets, default GO_PKG/... | |||
# | |||
# Build targets for compiling this Go package, i.e. arguments passed | |||
# to 'go install' | |||
# | |||
# e.g. GO_PKG_BUILD_PKG:=github.com/debian/ratt/cmd/... | |||
# | |||
# | |||
# GO_PKG_EXCLUDES - list of regular expressions, default empty | |||
# | |||
# Patterns to exclude from the build targets expanded from | |||
# GO_PKG_BUILD_PKG. | |||
# | |||
# e.g. GO_PKG_EXCLUDES:=examples/ | |||
# | |||
# | |||
# GO_PKG_GO_GENERATE - boolean (0 or 1), default false | |||
# | |||
# If true, 'go generate' will be called on all build targets (as | |||
# determined by GO_PKG_BUILD_PKG and GO_PKG_EXCLUDES). This is usually | |||
# not necessary. | |||
# | |||
# e.g. GO_PKG_GO_GENERATE:=1 | |||
# Credit for this package build process (GoPackage/Build/Configure and | |||
# GoPackage/Build/Compile) belong to Debian's dh-golang completely. | |||
# https://anonscm.debian.org/cgit/pkg-go/packages/dh-golang.git | |||
# for building packages, not user code | |||
GO_PKG_PATH:=/usr/share/gocode | |||
GO_PKG_BUILD_PKG?=$(GO_PKG)/... | |||
GO_PKG_WORK_DIR_NAME:=.go_work | |||
GO_PKG_WORK_DIR:=$(PKG_BUILD_DIR)/$(GO_PKG_WORK_DIR_NAME) | |||
GO_PKG_BUILD_DIR:=$(GO_PKG_WORK_DIR)/build | |||
GO_PKG_CACHE_DIR:=$(GO_PKG_WORK_DIR)/cache | |||
GO_PKG_TMP_DIR:=$(GO_PKG_WORK_DIR)/tmp | |||
GO_PKG_BUILD_BIN_DIR:=$(GO_PKG_BUILD_DIR)/bin$(if \ | |||
$(GO_HOST_TARGET_DIFFERENT),/$(GO_OS)_$(GO_ARCH)) | |||
GO_PKG_BUILD_DEPENDS_SRC:=$(STAGING_DIR)$(GO_PKG_PATH)/src | |||
# sstrip causes corrupted section header size | |||
ifneq ($(CONFIG_USE_SSTRIP),) | |||
ifneq ($(CONFIG_DEBUG),) | |||
GO_PKG_STRIP_ARGS:=--strip-unneeded --remove-section=.comment --remove-section=.note | |||
else | |||
GO_PKG_STRIP_ARGS:=--strip-all | |||
endif | |||
STRIP:=$(TARGET_CROSS)strip $(GO_PKG_STRIP_ARGS) | |||
RSTRIP= \ | |||
export CROSS="$(TARGET_CROSS)" \ | |||
$(if $(PKG_BUILD_ID),KEEP_BUILD_ID=1) \ | |||
$(if $(CONFIG_KERNEL_KALLSYMS),NO_RENAME=1) \ | |||
$(if $(CONFIG_KERNEL_PROFILING),KEEP_SYMBOLS=1); \ | |||
NM="$(TARGET_CROSS)nm" \ | |||
STRIP="$(STRIP)" \ | |||
STRIP_KMOD="$(SCRIPT_DIR)/strip-kmod.sh" \ | |||
PATCHELF="$(STAGING_DIR_HOST)/bin/patchelf" \ | |||
$(SCRIPT_DIR)/rstrip.sh | |||
endif | |||
define GoPackage/GoSubMenu | |||
SUBMENU:=Go | |||
SECTION:=lang | |||
CATEGORY:=Languages | |||
endef | |||
define GoPackage/Environment | |||
GOOS=$(GO_OS) \ | |||
GOARCH=$(GO_ARCH) \ | |||
GO386=$(GO_386) \ | |||
GOARM=$(GO_ARM) \ | |||
GOMIPS=$(GO_MIPS) \ | |||
CGO_ENABLED=1 \ | |||
CGO_CFLAGS="$(filter-out $(GO_CFLAGS_TO_REMOVE),$(TARGET_CFLAGS))" \ | |||
CGO_CPPFLAGS="$(TARGET_CPPFLAGS)" \ | |||
CGO_CXXFLAGS="$(filter-out $(GO_CFLAGS_TO_REMOVE),$(TARGET_CXXFLAGS))" | |||
endef | |||
# false if directory does not exist | |||
GoPackage/is_dir_not_empty=$$$$($(FIND) $(1) -maxdepth 0 -type d \! -empty 2>/dev/null) | |||
GoPackage/has_binaries=$(call GoPackage/is_dir_not_empty,$(GO_PKG_BUILD_BIN_DIR)) | |||
define GoPackage/Build/Configure | |||
( \ | |||
cd $(PKG_BUILD_DIR) ; \ | |||
mkdir -p $(GO_PKG_BUILD_DIR)/bin $(GO_PKG_BUILD_DIR)/src \ | |||
$(GO_PKG_CACHE_DIR) $(GO_PKG_TMP_DIR) ; \ | |||
\ | |||
files=$$$$($(FIND) ./ \ | |||
-type d -a \( -path './.git' -o -path './$(GO_PKG_WORK_DIR_NAME)' \) -prune -o \ | |||
\! -type d -print | \ | |||
sed 's|^\./||') ; \ | |||
\ | |||
if [ "$(GO_PKG_INSTALL_ALL)" != 1 ]; then \ | |||
code=$$$$(echo "$$$$files" | grep '\.\(c\|cc\|go\|h\|hh\|proto\|s\)$$$$') ; \ | |||
testdata=$$$$(echo "$$$$files" | grep '\(^\|/\)testdata/') ; \ | |||
\ | |||
for pattern in $(GO_PKG_INSTALL_EXTRA); do \ | |||
extra=$$$$(echo "$$$$extra"; echo "$$$$files" | grep "$$$$pattern") ; \ | |||
done ; \ | |||
\ | |||
files=$$$$(echo "$$$$code"; echo "$$$$testdata"; echo "$$$$extra") ; \ | |||
files=$$$$(echo "$$$$files" | grep -v '^[[:space:]]*$$$$' | sort -u) ; \ | |||
fi ; \ | |||
\ | |||
echo "Copying files from $(PKG_BUILD_DIR) into $(GO_PKG_BUILD_DIR)/src/$(GO_PKG)" ; \ | |||
for file in $$$$files; do \ | |||
echo $$$$file ; \ | |||
dest=$(GO_PKG_BUILD_DIR)/src/$(GO_PKG)/$$$$file ; \ | |||
mkdir -p $$$$(dirname $$$$dest) ; \ | |||
$(CP) $$$$file $$$$dest ; \ | |||
done ; \ | |||
\ | |||
link_contents() { \ | |||
local src=$$$$1 ; \ | |||
local dest=$$$$2 ; \ | |||
local dirs dir base ; \ | |||
\ | |||
if [ -n "$$$$($(FIND) $$$$src -mindepth 1 -maxdepth 1 -name '*.go' \! -type d)" ]; then \ | |||
echo "$$$$src is already a Go library" ; \ | |||
return 1 ; \ | |||
fi ; \ | |||
\ | |||
dirs=$$$$($(FIND) $$$$src -mindepth 1 -maxdepth 1 -type d) ; \ | |||
for dir in $$$$dirs; do \ | |||
base=$$$$(basename $$$$dir) ; \ | |||
if [ -d $$$$dest/$$$$base ]; then \ | |||
case $$$$dir in \ | |||
*$(GO_PKG_PATH)/src/$(GO_PKG)) \ | |||
echo "$(GO_PKG) is already installed. Please check for circular dependencies." ;; \ | |||
*) \ | |||
link_contents $$$$src/$$$$base $$$$dest/$$$$base ;; \ | |||
esac ; \ | |||
else \ | |||
echo "...$$$${src#$(GO_PKG_BUILD_DEPENDS_SRC)}/$$$$base" ; \ | |||
$(LN) $$$$src/$$$$base $$$$dest/$$$$base ; \ | |||
fi ; \ | |||
done ; \ | |||
} ; \ | |||
\ | |||
if [ "$(GO_PKG_SOURCE_ONLY)" != 1 ]; then \ | |||
if [ -d $(GO_PKG_BUILD_DEPENDS_SRC) ]; then \ | |||
echo "Symlinking directories from $(GO_PKG_BUILD_DEPENDS_SRC) into $(GO_PKG_BUILD_DIR)/src" ; \ | |||
link_contents $(GO_PKG_BUILD_DEPENDS_SRC) $(GO_PKG_BUILD_DIR)/src ; \ | |||
else \ | |||
echo "$(GO_PKG_BUILD_DEPENDS_SRC) does not exist, skipping symlinks" ; \ | |||
fi ; \ | |||
else \ | |||
echo "Not building binaries, skipping symlinks" ; \ | |||
fi ; \ | |||
) | |||
endef | |||
define GoPackage/Build/Compile | |||
( \ | |||
cd $(GO_PKG_BUILD_DIR) ; \ | |||
export GOPATH=$(GO_PKG_BUILD_DIR) \ | |||
GOCACHE=$(GO_PKG_CACHE_DIR) \ | |||
GOTMPDIR=$(GO_PKG_TMP_DIR) \ | |||
GOROOT_FINAL=$(GO_TARGET_ROOT) \ | |||
CC=$(TARGET_CC) \ | |||
CXX=$(TARGET_CXX) \ | |||
$(call GoPackage/Environment) ; \ | |||
\ | |||
targets=$$$$(go list $(GO_PKG_BUILD_PKG)) ; \ | |||
for pattern in $(GO_PKG_EXCLUDES); do \ | |||
targets=$$$$(echo "$$$$targets" | grep -v "$$$$pattern") ; \ | |||
done ; \ | |||
\ | |||
if [ "$(GO_PKG_GO_GENERATE)" = 1 ]; then \ | |||
go generate -v $$$$targets ; \ | |||
fi ; \ | |||
\ | |||
if [ "$(GO_PKG_SOURCE_ONLY)" != 1 ]; then \ | |||
case $(GO_ARCH) in \ | |||
arm) installsuffix="-installsuffix v$(GO_ARM)" ;; \ | |||
mips|mipsle) installsuffix="-installsuffix $(GO_MIPS)" ;; \ | |||
esac ; \ | |||
trimpath="all=-trimpath=$(GO_PKG_BUILD_DIR)" ; \ | |||
ldflags="all=-linkmode external -extldflags '$(TARGET_LDFLAGS)'" ; \ | |||
go install $$$$installsuffix -gcflags "$$$$trimpath" -asmflags "$$$$trimpath" -ldflags "$$$$ldflags" -v $$$$targets ; \ | |||
retval=$$$$? ; \ | |||
\ | |||
if [ "$$$$retval" -eq 0 ] && [ -z "$(call GoPackage/has_binaries)" ]; then \ | |||
echo "No binaries were generated, consider adding GO_PKG_SOURCE_ONLY:=1 to Makefile" ; \ | |||
fi ; \ | |||
fi ; \ | |||
exit $$$$retval ; \ | |||
) | |||
endef | |||
define GoPackage/Build/InstallDev | |||
$(call GoPackage/Package/Install/Src,$(1)) | |||
endef | |||
define GoPackage/Package/Install/Bin | |||
if [ -n "$(call GoPackage/has_binaries)" ]; then \ | |||
$(INSTALL_DIR) $(1)/usr/bin ; \ | |||
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/* $(1)/usr/bin/ ; \ | |||
fi | |||
endef | |||
define GoPackage/Package/Install/Src | |||
dir=$$$$(dirname $(GO_PKG)) ; \ | |||
$(INSTALL_DIR) $(1)$(GO_PKG_PATH)/src/$$$$dir ; \ | |||
$(CP) $(GO_PKG_BUILD_DIR)/src/$(GO_PKG) $(1)$(GO_PKG_PATH)/src/$$$$dir/ | |||
endef | |||
define GoPackage/Package/Install | |||
$(call GoPackage/Package/Install/Bin,$(1)) | |||
$(call GoPackage/Package/Install/Src,$(1)) | |||
endef | |||
ifneq ($(GO_PKG),) | |||
Build/Configure=$(call GoPackage/Build/Configure) | |||
Build/Compile=$(call GoPackage/Build/Compile) | |||
Build/InstallDev=$(call GoPackage/Build/InstallDev,$(1)) | |||
endif | |||
define GoPackage | |||
ifndef Package/$(1)/install | |||
Package/$(1)/install=$$(call GoPackage/Package/Install,$$(1)) | |||
endif | |||
endef | |||
define GoBinPackage | |||
ifndef Package/$(1)/install | |||
Package/$(1)/install=$$(call GoPackage/Package/Install/Bin,$$(1)) | |||
endif | |||
endef | |||
define GoSrcPackage | |||
ifndef Package/$(1)/install | |||
Package/$(1)/install=$$(call GoPackage/Package/Install/Src,$$(1)) | |||
endif | |||
endef |
@ -0,0 +1,72 @@ | |||
# | |||
# Copyright (C) 2018 Jeffery To | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
ifeq ($(origin GO_INCLUDE_DIR),undefined) | |||
GO_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST))) | |||
endif | |||
include $(GO_INCLUDE_DIR)/golang-version.mk | |||
unexport \ | |||
GOARCH GOBIN GOCACHE GODEBUG GOHOSTARCH GOOS GOPATH GORACE GOROOT GOTMPDIR GCCGO \ | |||
CGO_ENABLED \ | |||
CGO_CFLAGS CGO_CFLAGS_ALLOW CGO_CFLAGS_DISALLOW \ | |||
CGO_CPPFLAGS CGO_CPPFLAGS_ALLOW CGO_CPPFLAGS_DISALLOW \ | |||
CGO_CXXFLAGS CGO_CXXFLAGS_ALLOW CGO_CXXFLAGS_DISALLOW \ | |||
CGO_FFLAGS CGO_FFLAGS_ALLOW CGO_FFLAGS_DISALLOW \ | |||
CGO_LDFLAGS CGO_LDFLAGS_ALLOW CGO_LDFLAGS_DISALLOW \ | |||
GOARM GO386 GOMIPS \ | |||
GOROOT_FINAL GO_EXTLINK_ENABLED GIT_ALLOW_PROTOCOL \ | |||
CC_FOR_TARGET CXX_FOR_TARGET GO_DISTFLAGS GO_GCFLAGS GO_LDFLAGS GOBUILDTIMELOGFILE GOROOT_BOOTSTRAP \ | |||
BOOT_GO_GCFLAGS GOEXPERIMENT GOBOOTSTRAP_TOOLEXEC | |||
# there are more magic environment variables to track down, but ain't nobody got time for that | |||
go_arch=$(subst \ | |||
aarch64,arm64,$(subst \ | |||
i386,386,$(subst \ | |||
mipsel,mipsle,$(subst \ | |||
mips64el,mips64le,$(subst \ | |||
powerpc64,ppc64,$(subst \ | |||
x86_64,amd64,$(1))))))) | |||
GO_OS:=linux | |||
GO_ARCH:=$(call go_arch,$(ARCH)) | |||
GO_OS_ARCH:=$(GO_OS)_$(GO_ARCH) | |||
GO_HOST_OS:=$(call tolower,$(HOST_OS)) | |||
GO_HOST_ARCH:=$(call go_arch,$(subst \ | |||
armv6l,arm,$(subst \ | |||
armv7l,arm,$(subst \ | |||
i486,i386,$(subst \ | |||
i586,i386,$(subst \ | |||
i686,i386,$(HOST_ARCH))))))) | |||
GO_HOST_OS_ARCH:=$(GO_HOST_OS)_$(GO_HOST_ARCH) | |||
GO_HOST_TARGET_SAME:=$(if $(and $(findstring $(GO_OS_ARCH),$(GO_HOST_OS_ARCH)),$(findstring $(GO_HOST_OS_ARCH),$(GO_OS_ARCH))),1) | |||
GO_HOST_TARGET_DIFFERENT:=$(if $(GO_HOST_TARGET_SAME),,1) | |||
# ensure binaries can run on older CPUs | |||
GO_386:=387 | |||
GO_ARM:=$(if $(CONFIG_arm_v7),7,$(if $(CONFIG_arm_v6),6,$(if $(findstring $(GO_ARCH),arm),5,))) | |||
GO_MIPS:=$(if $(filter $(GO_ARCH),mips mipsle),$(if $(CONFIG_HAS_FPU),hardfloat,softfloat),) | |||
# -fno-plt: causes "unexpected GOT reloc for non-dynamic symbol" errors | |||
# -mips32r2: conflicts with -march=mips32 set by go | |||
GO_CFLAGS_TO_REMOVE:=$(if \ | |||
$(filter $(GO_ARCH),386),-fno-plt,$(if \ | |||
$(filter $(GO_ARCH),mips mipsle),-mips32r2,)) | |||
# mips64 / mips64el doesn't have softfloat support yet | |||
# https://github.com/golang/go/issues/14635 | |||
GO_ARCH_DEPENDS:=@(aarch64||arm||i386||i686||mips||mipsel||powerpc64||x86_64) | |||
GO_TARGET_PREFIX:=/usr | |||
GO_TARGET_VERSION_ID:=$(GO_VERSION_MAJOR_MINOR) | |||
GO_TARGET_ROOT:=$(GO_TARGET_PREFIX)/lib/go-$(GO_TARGET_VERSION_ID) |
@ -0,0 +1,14 @@ | |||
# | |||
# Copyright (C) 2018 Jeffery To | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
ifeq ($(origin GO_INCLUDE_DIR),undefined) | |||
GO_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST))) | |||
endif | |||
GO_VERSION_MAJOR_MINOR:=1.10 | |||
GO_VERSION_PATCH:= |
@ -0,0 +1,277 @@ | |||
# | |||
# Copyright (C) 2018 Jeffery To | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
include ../golang-version.mk | |||
PKG_NAME:=golang | |||
PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH)) | |||
PKG_RELEASE:=1 | |||
PKG_SOURCE:=go$(PKG_VERSION).src.tar.gz | |||
PKG_SOURCE_URL:=https://golang.org/dl/ | |||
PKG_HASH:=f3de49289405fda5fd1483a8fe6bd2fa5469e005fd567df64485c4fa000c7f24 | |||
PKG_LICENSE:=BSD-3-Clause | |||
PKG_LICENSE_FILES:=LICENSE | |||
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com> | |||
PKG_BUILD_DEPENDS:=golang/host | |||
PKG_BUILD_DIR:=$(BUILD_DIR)/go-$(PKG_VERSION) | |||
PKG_BUILD_PARALLEL:=1 | |||
PKG_USE_MIPS16:=0 | |||
PKG_GO_WORK_DIR:=$(PKG_BUILD_DIR)/.go_work | |||
PKG_GO_HOST_CACHE_DIR:=$(PKG_GO_WORK_DIR)/host_cache | |||
PKG_GO_TARGET_CACHE_DIR:=$(PKG_GO_WORK_DIR)/target_cache | |||
PKG_GO_TMP_DIR:=$(PKG_GO_WORK_DIR)/tmp | |||
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/go-$(PKG_VERSION) | |||
HOST_BUILD_PARALLEL:=1 | |||
HOST_GO_PREFIX:=$(STAGING_DIR_HOSTPKG) | |||
HOST_GO_VERSION_ID:=cross | |||
HOST_GO_ROOT:=$(HOST_GO_PREFIX)/lib/go-$(HOST_GO_VERSION_ID) | |||
HOST_GO_VALID_OS_ARCH:= \ | |||
android_arm \ | |||
darwin_386 darwin_amd64 darwin_arm darwin_arm64 \ | |||
dragonfly_amd64 \ | |||
freebsd_386 freebsd_amd64 freebsd_arm \ | |||
linux_386 linux_amd64 linux_arm linux_arm64 \ | |||
netbsd_386 netbsd_amd64 netbsd_arm \ | |||
openbsd_386 openbsd_amd64 openbsd_arm \ | |||
plan9_386 plan9_amd64 \ | |||
solaris_amd64 \ | |||
windows_386 windows_amd64 \ | |||
\ | |||
linux_ppc64 linux_ppc64le linux_mips linux_mipsle linux_mips64 linux_mips64le | |||
BOOTSTRAP_SOURCE_PROTO:=git | |||
BOOTSTRAP_SOURCE_URL:=https://go.googlesource.com/go | |||
BOOTSTRAP_SOURCE_VERSION:=4d5426a570c2820c5894a61b52e3dc147e4e7925 | |||
BOOTSTRAP_SOURCE_DATE:=20170926 | |||
BOOTSTRAP_MIRROR_HASH:=a3e26ee7c96486c841d29cbea3bf548ce2d999b9235275091cbe60ae6efa4cb1 | |||
BOOTSTRAP_VERSION:=$(BOOTSTRAP_SOURCE_DATE)-$(call version_abbrev,$(BOOTSTRAP_SOURCE_VERSION)) | |||
BOOTSTRAP_SOURCE_SUBDIR:=golang-bootstrap-$(BOOTSTRAP_VERSION) | |||
BOOTSTRAP_SOURCE:=$(BOOTSTRAP_SOURCE_SUBDIR).tar.xz | |||
BOOTSTRAP_BUILD_DIR:=$(HOST_BUILD_DIR)/.go_bootstrap | |||
BOOTSTRAP_GO_VALID_OS_ARCH:= \ | |||
darwin_386 darwin_amd64 \ | |||
dragonfly_386 dragonfly_amd64 \ | |||
freebsd_386 freebsd_amd64 freebsd_arm \ | |||
linux_386 linux_amd64 linux_arm \ | |||
netbsd_386 netbsd_amd64 netbsd_arm \ | |||
openbsd_386 openbsd_amd64 \ | |||
plan9_386 plan9_amd64 \ | |||
solaris_amd64 \ | |||
windows_386 windows_amd64 | |||
include $(INCLUDE_DIR)/host-build.mk | |||
include $(INCLUDE_DIR)/package.mk | |||
include ../golang-compiler.mk | |||
include ../golang-package.mk | |||
PKG_UNPACK:=$(HOST_TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE) | |||
HOST_UNPACK:=$(HOST_TAR) -C $(HOST_BUILD_DIR) --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE) | |||
BOOTSTRAP_UNPACK:=$(HOST_TAR) -C $(BOOTSTRAP_BUILD_DIR) --strip-components=1 -xJf $(DL_DIR)/$(BOOTSTRAP_SOURCE) | |||
# don't strip ELF executables in test data (and go itself) | |||
RSTRIP:=: | |||
STRIP:=: | |||
define Package/golang/Default | |||
$(call GoPackage/GoSubMenu) | |||
TITLE:=Go programming language | |||
URL:=https://golang.org/ | |||
DEPENDS:=$(GO_ARCH_DEPENDS) | |||
endef | |||
define Package/golang/Default/description | |||
The Go programming language is an open source project to make | |||
programmers more productive. | |||
Go is expressive, concise, clean, and efficient. Its concurrency | |||
mechanisms make it easy to write programs that get the most out of | |||
multicore and networked machines, while its novel type system enables | |||
flexible and modular program construction. Go compiles quickly to | |||
machine code yet has the convenience of garbage collection and the power | |||
of run-time reflection. It's a fast, statically typed, compiled language | |||
that feels like a dynamically typed, interpreted language. | |||
endef | |||
# go tool requires source present: | |||
# https://github.com/golang/go/issues/4635 | |||
define Package/golang | |||
$(call Package/golang/Default) | |||
TITLE+= (compiler) | |||
DEPENDS+= +golang-src | |||
endef | |||
define Package/golang/description | |||
$(call Package/golang/Default/description) | |||
This package provides an assembler, compiler, linker, and compiled | |||
libraries for the Go programming language. | |||
endef | |||
define Package/golang-doc | |||
$(call Package/golang/Default) | |||
TITLE+= (documentation) | |||
endef | |||
define Package/golang-doc/description | |||
$(call Package/golang/Default/description) | |||
This package provides the documentation for the Go programming language. | |||
endef | |||
define Package/golang-src | |||
$(call Package/golang/Default) | |||
TITLE+= (source files) | |||
endef | |||
define Package/golang-src/description | |||
$(call Package/golang/Default/description) | |||
This package provides the Go programming language source files needed | |||
for cross-compilation. | |||
endef | |||
define Download/golang-bootstrap | |||
FILE:=$(BOOTSTRAP_SOURCE) | |||
URL:=$(BOOTSTRAP_SOURCE_URL) | |||
SUBDIR:=$(BOOTSTRAP_SOURCE_SUBDIR) | |||
PROTO:=$(BOOTSTRAP_SOURCE_PROTO) | |||
MIRROR_HASH:=$(BOOTSTRAP_MIRROR_HASH) | |||
VERSION:=$(BOOTSTRAP_SOURCE_VERSION) | |||
endef | |||
$(eval $(call Download,golang-bootstrap)) | |||
$(eval $(call GoCompiler/AddProfile,Bootstrap,$(BOOTSTRAP_BUILD_DIR),,bootstrap,$(GO_HOST_OS_ARCH))) | |||
$(eval $(call GoCompiler/AddProfile,Host,$(HOST_BUILD_DIR),$(HOST_GO_PREFIX),$(HOST_GO_VERSION_ID),$(GO_HOST_OS_ARCH))) | |||
$(eval $(call GoCompiler/AddProfile,Package,$(PKG_BUILD_DIR),$(GO_TARGET_PREFIX),$(GO_TARGET_VERSION_ID),$(GO_OS_ARCH))) | |||
define Host/Prepare | |||
$(call Host/Prepare/Default) | |||
mkdir -p $(BOOTSTRAP_BUILD_DIR) | |||
$(BOOTSTRAP_UNPACK) | |||
endef | |||
define Host/Compile | |||
$(call GoCompiler/Bootstrap/CheckHost,$(BOOTSTRAP_GO_VALID_OS_ARCH)) | |||
$(call GoCompiler/Host/CheckHost,$(HOST_GO_VALID_OS_ARCH)) | |||
$(call GoCompiler/Bootstrap/Make, \ | |||
CC=$(HOSTCC_NOCACHE) \ | |||
CXX=$(HOSTCXX_NOCACHE) \ | |||
) | |||
$(call GoCompiler/Host/Make, \ | |||
GOROOT_BOOTSTRAP=$(BOOTSTRAP_BUILD_DIR) \ | |||
CC=$(HOSTCC_NOCACHE) \ | |||
CXX=$(HOSTCXX_NOCACHE) \ | |||
) | |||
endef | |||
# if host and target os/arch are the same, | |||
# when go compiles a program, it will use the host std lib | |||
# so remove it now and force go to rebuild std for target later | |||
define Host/Install | |||
$(call GoCompiler/Host/Install/Bin,) | |||
$(call GoCompiler/Host/Install/Src,) | |||
$(call GoCompiler/Host/Install/BinLinks,) | |||
rm -rf $(HOST_GO_ROOT)/pkg/$(GO_HOST_OS_ARCH) | |||
$(INSTALL_DIR) $(HOST_GO_ROOT)/openwrt | |||
$(INSTALL_BIN) ./files/go-gcc-helper $(HOST_GO_ROOT)/openwrt/ | |||
$(LN) go-gcc-helper $(HOST_GO_ROOT)/openwrt/gcc | |||
$(LN) go-gcc-helper $(HOST_GO_ROOT)/openwrt/g++ | |||
endef | |||
define Host/Uninstall | |||
rm -rf $(HOST_GO_ROOT)/openwrt | |||
$(call GoCompiler/Host/Uninstall/BinLinks,) | |||
$(call GoCompiler/Host/Uninstall,) | |||
endef | |||
define Build/Compile | |||
mkdir -p \ | |||
$(PKG_GO_HOST_CACHE_DIR) \ | |||
$(PKG_GO_TARGET_CACHE_DIR) \ | |||
$(PKG_GO_TMP_DIR) | |||
@echo "Building target Go first stage" | |||
$(call GoCompiler/Package/Make, \ | |||
GOROOT_BOOTSTRAP=$(HOST_GO_ROOT) \ | |||
GOCACHE=$(PKG_GO_HOST_CACHE_DIR) \ | |||
GOTMPDIR=$(PKG_GO_TMP_DIR) \ | |||
GO_GCC_HELPER_CC="$(HOSTCC)" \ | |||
GO_GCC_HELPER_CXX="$(HOSTCXX)" \ | |||
GO_GCC_HELPER_PATH=$$$$PATH \ | |||
CC=gcc \ | |||
CXX=g++ \ | |||
PKG_CONFIG=pkg-config \ | |||
PATH=$(HOST_GO_ROOT)/openwrt:$$$$PATH \ | |||
) | |||
@echo "Building target Go second stage" | |||
( \ | |||
cd $(PKG_BUILD_DIR)/bin ; \ | |||
$(CP) go go-host ; \ | |||
GOROOT_FINAL=$(GO_TARGET_ROOT) \ | |||
GOCACHE=$(PKG_GO_TARGET_CACHE_DIR) \ | |||
GOTMPDIR=$(PKG_GO_TMP_DIR) \ | |||
GO_GCC_HELPER_CC="$(TARGET_CC)" \ | |||
GO_GCC_HELPER_CXX="$(TARGET_CXX)" \ | |||
GO_GCC_HELPER_PATH=$$$$PATH \ | |||
CC=gcc \ | |||
CXX=g++ \ | |||
PKG_CONFIG=pkg-config \ | |||
PATH=$(HOST_GO_ROOT)/openwrt:$$$$PATH \ | |||
$(call GoPackage/Environment) \ | |||
./go-host install -a -v std cmd ; \ | |||
retval=$$$$? ; \ | |||
rm -f go-host ; \ | |||
exit $$$$retval ; \ | |||
) | |||
endef | |||
define Package/golang/install | |||
$(call GoCompiler/Package/Install/Bin,$(1)$(GO_TARGET_PREFIX)) | |||
$(call GoCompiler/Package/Install/BinLinks,$(1)$(GO_TARGET_PREFIX)) | |||
endef | |||
define Package/golang-doc/install | |||
$(call GoCompiler/Package/Install/Doc,$(1)$(GO_TARGET_PREFIX)) | |||
endef | |||
define Package/golang-src/install | |||
$(call GoCompiler/Package/Install/Src,$(1)$(GO_TARGET_PREFIX)) | |||
endef | |||
# src/debug contains ELF executables as test data | |||
# and they reference these libraries | |||
# we need to call this in Package/$(1)/extra_provides | |||
# to pass CheckDependencies in include/package-ipkg.mk | |||
define Package/golang-src/extra_provides | |||
echo 'libc.so.6' | |||
endef | |||
$(eval $(call HostBuild)) | |||
$(eval $(call BuildPackage,golang)) | |||
$(eval $(call BuildPackage,golang-doc)) | |||
$(eval $(call BuildPackage,golang-src)) |
@ -0,0 +1,23 @@ | |||
#!/bin/sh | |||
me=go-gcc-helper | |||
name=$(basename $0) | |||
case $name in | |||
gcc) | |||
cmd=$GO_GCC_HELPER_CC | |||
;; | |||
g++) | |||
cmd=$GO_GCC_HELPER_CXX | |||
;; | |||
*) | |||
echo "$me: unknown command \"$name\"" | |||
exit 1 | |||
;; | |||
esac | |||
export PATH="$GO_GCC_HELPER_PATH" | |||
echo "$me: running $cmd $@" | |||
$cmd "$@" |
@ -0,0 +1,37 @@ | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PECL_NAME:=krb5 | |||
PECL_LONGNAME:=Bindings for the Kerberos library | |||
PKG_VERSION:=1.1.2 | |||
PKG_RELEASE:=1 | |||
PKG_HASH:=3301e047fc7dc3574da19b2a4b18e15feca5ad39db9335c3353a8e16b855c35b | |||
PKG_NAME:=php7-pecl-krb5 | |||
PKG_SOURCE:=$(PECL_NAME)-$(PKG_VERSION).tgz | |||
PKG_SOURCE_URL:=http://pecl.php.net/get/ | |||
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> | |||
PKG_LICENSE:=BSD | |||
PKG_LICENSE_FILES:=LICENSE | |||
PKG_BUILD_DEPENDS:=php7 | |||
PKG_BUILD_DIR:=$(BUILD_DIR)/pecl-php7/$(PECL_NAME)-$(PKG_VERSION) | |||
PKG_BUILD_PARALLEL:=1 | |||
PKG_FIXUP:=autoreconf | |||
include $(INCLUDE_DIR)/package.mk | |||
include $(INCLUDE_DIR)/nls.mk | |||
include ../php7/pecl.mk | |||
CONFIGURE_ARGS+= --with-krb5=shared,"$(STAGING_DIR)/usr" | |||
$(eval $(call PECLPackage,krb5,$(PECL_LONGNAME),+krb5-libs,30)) | |||
$(eval $(call BuildPackage,$(PKG_NAME))) |
@ -0,0 +1,37 @@ | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PECL_NAME:=mcrypt | |||
PECL_LONGNAME:=Bindings for the libmcrypt library | |||
PKG_VERSION:=1.0.1 | |||
PKG_RELEASE:=1 | |||
PKG_HASH:=a3b0e5493b5cd209ab780ee54733667293d369e6b7052b4a7dab9dd0def46ac6 | |||
PKG_NAME:=php7-pecl-mcrypt | |||
PKG_SOURCE:=$(PECL_NAME)-$(PKG_VERSION).tgz | |||
PKG_SOURCE_URL:=http://pecl.php.net/get/ | |||
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> | |||
PKG_LICENSE:=PHPv3.01 | |||
PKG_LICENSE_FILES:=LICENSE | |||
PKG_BUILD_DEPENDS:=php7 | |||
PKG_BUILD_DIR:=$(BUILD_DIR)/pecl-php7/$(PECL_NAME)-$(PKG_VERSION) | |||
PKG_BUILD_PARALLEL:=1 | |||
PKG_FIXUP:=autoreconf | |||
include $(INCLUDE_DIR)/package.mk | |||
include $(INCLUDE_DIR)/nls.mk | |||
include ../php7/pecl.mk | |||
CONFIGURE_ARGS+= --with-mcrypt=shared,"$(STAGING_DIR)/usr" | |||
$(eval $(call PECLPackage,mcrypt,$(PECL_LONGNAME),+libmcrypt +libltdl,30)) | |||
$(eval $(call BuildPackage,$(PKG_NAME))) |
@ -0,0 +1,132 @@ | |||
--- a/evhtp.c | |||
+++ b/evhtp.c | |||
@@ -1686,16 +1686,15 @@ _evhtp_ssl_thread_lock(int mode, int typ | |||
#endif | |||
static void | |||
_evhtp_ssl_delete_scache_ent(evhtp_ssl_ctx_t * ctx, evhtp_ssl_sess_t * sess) { | |||
- evhtp_t * htp; | |||
- evhtp_ssl_cfg_t * cfg; | |||
- unsigned char * sid; | |||
- unsigned int slen; | |||
+ evhtp_t * htp; | |||
+ evhtp_ssl_cfg_t * cfg; | |||
+ evhtp_ssl_data_t * sid; | |||
+ unsigned int slen; | |||
htp = (evhtp_t *)SSL_CTX_get_app_data(ctx); | |||
cfg = htp->ssl_cfg; | |||
- sid = sess->session_id; | |||
- slen = sess->session_id_length; | |||
+ sid = (evhtp_ssl_data_t *)SSL_SESSION_get_id(sess, &slen); | |||
if (cfg->scache_del) { | |||
(cfg->scache_del)(htp, sid, slen); | |||
@@ -1706,14 +1705,17 @@ static int | |||
_evhtp_ssl_add_scache_ent(evhtp_ssl_t * ssl, evhtp_ssl_sess_t * sess) { | |||
evhtp_connection_t * connection; | |||
evhtp_ssl_cfg_t * cfg; | |||
- unsigned char * sid; | |||
+ evhtp_ssl_data_t * sid; | |||
int slen; | |||
connection = (evhtp_connection_t *)SSL_get_app_data(ssl); | |||
- cfg = connection->htp->ssl_cfg; | |||
+ if (connection->htp == NULL) | |||
+ { | |||
+ return 0; /* We cannot get the ssl_cfg */ | |||
+ } | |||
- sid = sess->session_id; | |||
- slen = sess->session_id_length; | |||
+ cfg = connection->htp->ssl_cfg; | |||
+ sid = (evhtp_ssl_data_t *)SSL_SESSION_get_id(sess, &slen); | |||
SSL_set_timeout(sess, cfg->scache_timeout); | |||
@@ -1725,7 +1727,7 @@ _evhtp_ssl_add_scache_ent(evhtp_ssl_t * | |||
} | |||
static evhtp_ssl_sess_t * | |||
-_evhtp_ssl_get_scache_ent(evhtp_ssl_t * ssl, unsigned char * sid, int sid_len, int * copy) { | |||
+_evhtp_ssl_get_scache_ent(evhtp_ssl_t * ssl, evhtp_ssl_data_t * sid, int sid_len, int * copy) { | |||
evhtp_connection_t * connection; | |||
evhtp_ssl_cfg_t * cfg; | |||
evhtp_ssl_sess_t * sess; | |||
@@ -1767,12 +1769,12 @@ _evhtp_ssl_servername(evhtp_ssl_t * ssl, | |||
connection->vhost_via_sni = 1; | |||
SSL_set_SSL_CTX(ssl, evhtp_vhost->ssl_ctx); | |||
- SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx)); | |||
+ SSL_set_options(ssl, SSL_CTX_get_options(SSL_get_SSL_CTX(ssl))); | |||
if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || | |||
(SSL_num_renegotiations(ssl) == 0)) { | |||
- SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), | |||
- SSL_CTX_get_verify_callback(ssl->ctx)); | |||
+ SSL_set_verify(ssl, SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(ssl)), | |||
+ SSL_CTX_get_verify_callback(SSL_get_SSL_CTX(ssl))); | |||
} | |||
return SSL_TLSEXT_ERR_OK; | |||
@@ -3017,15 +3019,21 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_ | |||
return -1; | |||
} | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
SSL_library_init(); | |||
SSL_load_error_strings(); | |||
+#endif | |||
RAND_poll(); | |||
STACK_OF(SSL_COMP) * comp_methods = SSL_COMP_get_compression_methods(); | |||
sk_SSL_COMP_zero(comp_methods); | |||
htp->ssl_cfg = cfg; | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
htp->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); | |||
+#else | |||
+ htp->ssl_ctx = SSL_CTX_new(TLS_server_method()); | |||
+#endif | |||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L | |||
SSL_CTX_set_options(htp->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); | |||
@@ -3062,7 +3070,11 @@ evhtp_ssl_init(evhtp_t * htp, evhtp_ssl_ | |||
SSL_CTX_set_verify(htp->ssl_ctx, cfg->verify_peer, cfg->x509_verify_cb); | |||
if (cfg->x509_chk_issued_cb != NULL) { | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
htp->ssl_ctx->cert_store->check_issued = cfg->x509_chk_issued_cb; | |||
+#else | |||
+ X509_STORE_set_check_issued(SSL_CTX_get_cert_store(htp->ssl_ctx), cfg->x509_chk_issued_cb); | |||
+#endif | |||
} | |||
if (cfg->verify_depth) { | |||
--- a/evhtp.h | |||
+++ b/evhtp.h | |||
@@ -34,6 +34,11 @@ typedef SSL evhtp_ | |||
typedef SSL_CTX evhtp_ssl_ctx_t; | |||
typedef X509 evhtp_x509_t; | |||
typedef X509_STORE_CTX evhtp_x509_store_ctx_t; | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
+typedef unsigned char evhtp_ssl_data_t; | |||
+#else | |||
+typedef const unsigned char evhtp_ssl_data_t; | |||
+#endif | |||
#else | |||
typedef void evhtp_ssl_sess_t; | |||
typedef void evhtp_ssl_t; | |||
@@ -154,9 +159,9 @@ typedef int (*evhtp_headers_iterator)(ev | |||
typedef int (*evhtp_ssl_verify_cb)(int pre_verify, evhtp_x509_store_ctx_t * ctx); | |||
typedef int (*evhtp_ssl_chk_issued_cb)(evhtp_x509_store_ctx_t * ctx, evhtp_x509_t * x, evhtp_x509_t * issuer); | |||
-typedef int (*evhtp_ssl_scache_add)(evhtp_connection_t * connection, unsigned char * sid, int sid_len, evhtp_ssl_sess_t * sess); | |||
-typedef void (*evhtp_ssl_scache_del)(evhtp_t * htp, unsigned char * sid, int sid_len); | |||
-typedef evhtp_ssl_sess_t * (*evhtp_ssl_scache_get)(evhtp_connection_t * connection, unsigned char * sid, int sid_len); | |||
+typedef int (*evhtp_ssl_scache_add)(evhtp_connection_t * connection, evhtp_ssl_data_t * sid, int sid_len, evhtp_ssl_sess_t * sess); | |||
+typedef void (*evhtp_ssl_scache_del)(evhtp_t * htp, evhtp_ssl_data_t * sid, int sid_len); | |||
+typedef evhtp_ssl_sess_t * (*evhtp_ssl_scache_get)(evhtp_connection_t * connection, evhtp_ssl_data_t * sid, int sid_len); | |||
typedef void * (*evhtp_ssl_scache_init)(evhtp_t *); | |||
#define EVHTP_VERSION "1.1.6" |
@ -0,0 +1,15 @@ | |||
--- a/src/tls.c | |||
+++ b/src/tls.c | |||
@@ -63,10 +63,12 @@ static inline int tls_setup(shout_tls_t | |||
{ | |||
SSL_METHOD *meth; | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
SSL_library_init(); | |||
SSL_load_error_strings(); | |||
SSLeay_add_all_algorithms(); | |||
SSLeay_add_ssl_algorithms(); | |||
+#endif | |||
meth = TLSv1_client_method(); | |||
if (!meth) |
@ -0,0 +1,11 @@ | |||
--- a/configure.ac | |||
+++ b/configure.ac | |||
@@ -141,7 +141,7 @@ AC_ARG_ENABLE([openssl], | |||
else | |||
openssl="true" | |||
if test "x$enableval" = "xyes"; then | |||
- AC_CHECK_LIB([ssl], [SSL_library_init], [], [AC_MSG_ERROR([libssl not found])]) | |||
+ AC_CHECK_LIB([ssl], [SSL_CTX_new], [], [AC_MSG_ERROR([libssl not found])]) | |||
AC_CHECK_LIB([crypto], [SHA1_Init], [], [AC_MSG_ERROR([libcrypto not found])]) | |||
else | |||
AC_MSG_CHECKING([for openssl in $enableval]) |
@ -0,0 +1,86 @@ | |||
From c3f68d987c00284d91ad6599a013b7111662545b Mon Sep 17 00:00:00 2001 | |||
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | |||
Date: Fri, 2 Sep 2016 21:33:33 +0000 | |||
Subject: [PATCH] uw-imap: compile against openssl 1.1.0 | |||
I *think* I replaced access to cert->name with certificate's subject name. I | |||
assume that the re-aranged C-code is doing the same thing. A double check | |||
wouldn't hurt :) | |||
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | |||
--- | |||
src/osdep/unix/ssl_unix.c | 28 +++++++++++++++++----------- | |||
1 file changed, 17 insertions(+), 11 deletions(-) | |||
diff --git a/src/osdep/unix/ssl_unix.c b/src/osdep/unix/ssl_unix.c | |||
index 3bfdff3..836e9fa 100644 | |||
--- a/src/osdep/unix/ssl_unix.c | |||
+++ b/src/osdep/unix/ssl_unix.c | |||
@@ -59,7 +59,7 @@ typedef struct ssl_stream { | |||
static SSLSTREAM *ssl_start(TCPSTREAM *tstream,char *host,unsigned long flags); | |||
static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags); | |||
static int ssl_open_verify (int ok,X509_STORE_CTX *ctx); | |||
-static char *ssl_validate_cert (X509 *cert,char *host); | |||
+static char *ssl_validate_cert (X509 *cert,char *host, char *cert_subj); | |||
static long ssl_compare_hostnames (unsigned char *s,unsigned char *pat); | |||
static char *ssl_getline_work (SSLSTREAM *stream,unsigned long *size, | |||
long *contd); | |||
@@ -210,6 +210,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags) | |||
BIO *bio; | |||
X509 *cert; | |||
unsigned long sl,tl; | |||
+ char cert_subj[250]; | |||
char *s,*t,*err,tmp[MAILTMPLEN]; | |||
sslcertificatequery_t scq = | |||
(sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL); | |||
@@ -266,14 +267,19 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags) | |||
if (SSL_write (stream->con,"",0) < 0) | |||
return ssl_last_error ? ssl_last_error : "SSL negotiation failed"; | |||
/* need to validate host names? */ | |||
- if (!(flags & NET_NOVALIDATECERT) && | |||
- (err = ssl_validate_cert (cert = SSL_get_peer_certificate (stream->con), | |||
- host))) { | |||
- /* application callback */ | |||
- if (scq) return (*scq) (err,host,cert ? cert->name : "???") ? NIL : ""; | |||
+ if (!(flags & NET_NOVALIDATECERT)) { | |||
+ | |||
+ cert_subj[0] = '\0'; | |||
+ cert = SSL_get_peer_certificate(stream->con); | |||
+ if (cert) | |||
+ X509_NAME_oneline(X509_get_subject_name(cert), cert_subj, sizeof(cert_subj)); | |||
+ err = ssl_validate_cert (cert, host, cert_subj); | |||
+ if (err) | |||
+ /* application callback */ | |||
+ if (scq) return (*scq) (err,host,cert ? cert_subj : "???") ? NIL : ""; | |||
/* error message to return via mm_log() */ | |||
- sprintf (tmp,"*%.128s: %.255s",err,cert ? cert->name : "???"); | |||
- return ssl_last_error = cpystr (tmp); | |||
+ sprintf (tmp,"*%.128s: %.255s",err,cert ? cert_subj : "???"); | |||
+ return ssl_last_error = cpystr (tmp); | |||
} | |||
return NIL; | |||
} | |||
@@ -313,7 +319,7 @@ static int ssl_open_verify (int ok,X509_STORE_CTX *ctx) | |||
* Returns: NIL if validated, else string of error message | |||
*/ | |||
-static char *ssl_validate_cert (X509 *cert,char *host) | |||
+static char *ssl_validate_cert (X509 *cert,char *host, char *cert_subj) | |||
{ | |||
int i,n; | |||
char *s,*t,*ret; | |||
@@ -322,9 +328,9 @@ static char *ssl_validate_cert (X509 *cert,char *host) | |||
/* make sure have a certificate */ | |||
if (!cert) ret = "No certificate from server"; | |||
/* and that it has a name */ | |||
- else if (!cert->name) ret = "No name in certificate"; | |||
+ else if (cert_subj[0] == '\0') ret = "No name in certificate"; | |||
/* locate CN */ | |||
- else if (s = strstr (cert->name,"/CN=")) { | |||
+ else if (s = strstr (cert_subj,"/CN=")) { | |||
if (t = strchr (s += 4,'/')) *t = '\0'; | |||
/* host name matches pattern? */ | |||
ret = ssl_compare_hostnames (host,s) ? NIL : | |||
-- | |||
2.9.3 | |||
@ -0,0 +1,455 @@ | |||
--- a/sources/applications/applestreamingclient/include/protocols/aes/inboundaesprotocol.h | |||
+++ b/sources/applications/applestreamingclient/include/protocols/aes/inboundaesprotocol.h | |||
@@ -30,7 +30,7 @@ namespace app_applestreamingclient { | |||
private: | |||
IOBuffer _tempBuffer; | |||
IOBuffer _inputBuffer; | |||
- EVP_CIPHER_CTX _decContex; | |||
+ EVP_CIPHER_CTX *_decContex; | |||
bool _lastChunk; | |||
uint8_t *_pIV; | |||
uint8_t *_pKey; | |||
--- a/sources/applications/applestreamingclient/src/protocols/aes/inboundaesprotocol.cpp | |||
+++ b/sources/applications/applestreamingclient/src/protocols/aes/inboundaesprotocol.cpp | |||
@@ -31,13 +31,12 @@ InboundAESProtocol::InboundAESProtocol() | |||
memset(_pIV, 0, 16); | |||
_pKey = new uint8_t[16]; | |||
memset(_pKey, 0, 16); | |||
- memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX)); | |||
+ _decContex = EVP_CIPHER_CTX_new(); | |||
_totalDecrypted = 0; | |||
} | |||
InboundAESProtocol::~InboundAESProtocol() { | |||
- EVP_CIPHER_CTX_cleanup(&_decContex); | |||
- memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX)); | |||
+ EVP_CIPHER_CTX_free(_decContex); | |||
delete[] _pIV; | |||
delete[] _pKey; | |||
} | |||
@@ -60,11 +59,9 @@ bool InboundAESProtocol::Initialize(Vari | |||
_inputBuffer.IgnoreAll(); | |||
_tempBuffer.IgnoreAll(); | |||
- EVP_CIPHER_CTX_cleanup(&_decContex); | |||
- memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX)); | |||
- EVP_CIPHER_CTX_init(&_decContex); | |||
- EVP_DecryptInit_ex(&_decContex, EVP_aes_128_cbc(), NULL, _pKey, _pIV); | |||
- EVP_CIPHER_CTX_set_padding(&_decContex, 0); | |||
+ EVP_CIPHER_CTX_reset(_decContex); | |||
+ EVP_DecryptInit_ex(_decContex, EVP_aes_128_cbc(), NULL, _pKey, _pIV); | |||
+ EVP_CIPHER_CTX_set_padding(_decContex, 0); | |||
return true; | |||
} | |||
@@ -105,14 +102,14 @@ bool InboundAESProtocol::SignalInputData | |||
int decryptedFinalSize = 0; | |||
uint32_t padding = 0; | |||
- EVP_DecryptUpdate(&_decContex, pTempData, &decryptedSize, GETIBPOINTER(buffer), safeSize); | |||
+ EVP_DecryptUpdate(_decContex, pTempData, &decryptedSize, GETIBPOINTER(buffer), safeSize); | |||
_totalDecrypted += decryptedSize; | |||
//6. Decrypt leftovers | |||
bool transferCompleted = false; | |||
if (((HTTPBufferProtocol *) GetFarProtocol())->TransferCompleted()) { | |||
transferCompleted = true; | |||
- EVP_DecryptFinal_ex(&_decContex, | |||
+ EVP_DecryptFinal_ex(_decContex, | |||
pTempData + decryptedSize, | |||
&decryptedFinalSize); | |||
_totalDecrypted += decryptedFinalSize; | |||
--- a/sources/common/include/utils/misc/crypto.h | |||
+++ b/sources/common/include/utils/misc/crypto.h | |||
@@ -33,6 +33,7 @@ | |||
#include <openssl/aes.h> | |||
#include <openssl/engine.h> | |||
#include <openssl/conf.h> | |||
+#include "utils/misc/libcrypto-compat.h" | |||
/*! | |||
@class DHWrapper | |||
@@ -83,7 +84,7 @@ public: | |||
bool CopySharedKey(uint8_t *pDst, int32_t dstLength); | |||
private: | |||
void Cleanup(); | |||
- bool CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength); | |||
+ bool CopyKey(const BIGNUM *pNum, uint8_t *pDst, int32_t dstLength); | |||
}; | |||
DLLEXP void InitRC4Encryption(uint8_t *secretKey, uint8_t *pubKeyIn, uint8_t *pubKeyOut, | |||
--- a/sources/common/src/utils/misc/crypto.cpp | |||
+++ b/sources/common/src/utils/misc/crypto.cpp | |||
@@ -35,6 +35,7 @@ DHWrapper::~DHWrapper() { | |||
} | |||
bool DHWrapper::Initialize() { | |||
+ BIGNUM *p = NULL, *g = NULL; | |||
Cleanup(); | |||
//1. Create the DH | |||
@@ -46,42 +47,53 @@ bool DHWrapper::Initialize() { | |||
} | |||
//2. Create his internal p and g | |||
- _pDH->p = BN_new(); | |||
- if (_pDH->p == NULL) { | |||
+ p = BN_new(); | |||
+ if (p == NULL) { | |||
FATAL("Unable to create p"); | |||
- Cleanup(); | |||
- return false; | |||
+ goto return_error; | |||
} | |||
- _pDH->g = BN_new(); | |||
- if (_pDH->g == NULL) { | |||
+ g = BN_new(); | |||
+ if (g == NULL) { | |||
FATAL("Unable to create g"); | |||
- Cleanup(); | |||
- return false; | |||
+ goto return_error; | |||
} | |||
//3. initialize p, g and key length | |||
- if (BN_hex2bn(&_pDH->p, P1024) == 0) { | |||
+ if (BN_hex2bn(&p, P1024) == 0) { | |||
FATAL("Unable to parse P1024"); | |||
- Cleanup(); | |||
- return false; | |||
+ goto return_error; | |||
} | |||
- if (BN_set_word(_pDH->g, 2) != 1) { | |||
+ if (BN_set_word(g, 2) != 1) { | |||
FATAL("Unable to set g"); | |||
- Cleanup(); | |||
- return false; | |||
+ goto return_error; | |||
} | |||
- //4. Set the key length | |||
- _pDH->length = _bitsCount; | |||
+ //4. Set internal p and g | |||
+ if (DH_set0_pqg(_pDH, p, NULL, g) != 1) { | |||
+ FATAL("Unable to set internal p and g"); | |||
+ goto return_error; | |||
+ } | |||
+ p = g = NULL; | |||
- //5. Generate private and public key | |||
+ //5. Set the key length | |||
+ if (DH_set_length(_pDH, _bitsCount) != 1) { | |||
+ FATAL("Unable to set length"); | |||
+ goto return_error; | |||
+ } | |||
+ | |||
+ //6. Generate private and public key | |||
if (DH_generate_key(_pDH) != 1) { | |||
FATAL("Unable to generate DH public/private keys"); | |||
- Cleanup(); | |||
- return false; | |||
+ goto return_error; | |||
} | |||
return true; | |||
+ | |||
+return_error: | |||
+ if (p != NULL) BN_free(p); | |||
+ if (g != NULL) BN_free(g); | |||
+ Cleanup(); | |||
+ return false; | |||
} | |||
bool DHWrapper::CopyPublicKey(uint8_t *pDst, int32_t dstLength) { | |||
@@ -90,7 +102,9 @@ bool DHWrapper::CopyPublicKey(uint8_t *p | |||
return false; | |||
} | |||
- return CopyKey(_pDH->pub_key, pDst, dstLength); | |||
+ const BIGNUM *pub_key; | |||
+ DH_get0_key(_pDH, &pub_key, NULL); | |||
+ return CopyKey(pub_key, pDst, dstLength); | |||
} | |||
bool DHWrapper::CopyPrivateKey(uint8_t *pDst, int32_t dstLength) { | |||
@@ -99,7 +113,9 @@ bool DHWrapper::CopyPrivateKey(uint8_t * | |||
return false; | |||
} | |||
- return CopyKey(_pDH->priv_key, pDst, dstLength); | |||
+ const BIGNUM *priv_key; | |||
+ DH_get0_key(_pDH, NULL, &priv_key); | |||
+ return CopyKey(priv_key, pDst, dstLength); | |||
} | |||
bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length) { | |||
@@ -153,14 +169,6 @@ bool DHWrapper::CopySharedKey(uint8_t *p | |||
void DHWrapper::Cleanup() { | |||
if (_pDH != NULL) { | |||
- if (_pDH->p != NULL) { | |||
- BN_free(_pDH->p); | |||
- _pDH->p = NULL; | |||
- } | |||
- if (_pDH->g != NULL) { | |||
- BN_free(_pDH->g); | |||
- _pDH->g = NULL; | |||
- } | |||
DH_free(_pDH); | |||
_pDH = NULL; | |||
} | |||
@@ -177,7 +185,7 @@ void DHWrapper::Cleanup() { | |||
} | |||
} | |||
-bool DHWrapper::CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength) { | |||
+bool DHWrapper::CopyKey(const BIGNUM *pNum, uint8_t *pDst, int32_t dstLength) { | |||
int32_t keySize = BN_num_bytes(pNum); | |||
if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)) { | |||
FATAL("CopyPublicKey failed due to either invalid DH state or invalid call"); | |||
@@ -197,20 +205,21 @@ void InitRC4Encryption(uint8_t *secretKe | |||
uint8_t digest[SHA256_DIGEST_LENGTH]; | |||
unsigned int digestLen = 0; | |||
- HMAC_CTX ctx; | |||
- HMAC_CTX_init(&ctx); | |||
- HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0); | |||
- HMAC_Update(&ctx, pubKeyIn, 128); | |||
- HMAC_Final(&ctx, digest, &digestLen); | |||
- HMAC_CTX_cleanup(&ctx); | |||
+ HMAC_CTX *ctx; | |||
+ ctx = HMAC_CTX_new(); | |||
+ if (ctx == NULL) | |||
+ return; | |||
+ HMAC_Init_ex(ctx, secretKey, 128, EVP_sha256(), 0); | |||
+ HMAC_Update(ctx, pubKeyIn, 128); | |||
+ HMAC_Final(ctx, digest, &digestLen); | |||
+ HMAC_CTX_reset(ctx); | |||
RC4_set_key(rc4keyOut, 16, digest); | |||
- HMAC_CTX_init(&ctx); | |||
- HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0); | |||
- HMAC_Update(&ctx, pubKeyOut, 128); | |||
- HMAC_Final(&ctx, digest, &digestLen); | |||
- HMAC_CTX_cleanup(&ctx); | |||
+ HMAC_Init_ex(ctx, secretKey, 128, EVP_sha256(), 0); | |||
+ HMAC_Update(ctx, pubKeyOut, 128); | |||
+ HMAC_Final(ctx, digest, &digestLen); | |||
+ HMAC_CTX_free(ctx); | |||
RC4_set_key(rc4keyIn, 16, digest); | |||
} | |||
@@ -220,14 +229,17 @@ string md5(string source, bool textResul | |||
} | |||
string md5(uint8_t *pBuffer, uint32_t length, bool textResult) { | |||
- EVP_MD_CTX mdctx; | |||
+ EVP_MD_CTX *mdctx; | |||
unsigned char md_value[EVP_MAX_MD_SIZE]; | |||
unsigned int md_len; | |||
- EVP_DigestInit(&mdctx, EVP_md5()); | |||
- EVP_DigestUpdate(&mdctx, pBuffer, length); | |||
- EVP_DigestFinal_ex(&mdctx, md_value, &md_len); | |||
- EVP_MD_CTX_cleanup(&mdctx); | |||
+ mdctx = EVP_MD_CTX_new(); | |||
+ if (mdctx == NULL) | |||
+ return ""; | |||
+ EVP_DigestInit(mdctx, EVP_md5()); | |||
+ EVP_DigestUpdate(mdctx, pBuffer, length); | |||
+ EVP_DigestFinal_ex(mdctx, md_value, &md_len); | |||
+ EVP_MD_CTX_free(mdctx); | |||
if (textResult) { | |||
string result = ""; | |||
@@ -244,12 +256,12 @@ void HMACsha256(const void *pData, uint3 | |||
const void *pKey, uint32_t keyLength, void *pResult) { | |||
unsigned int digestLen; | |||
- HMAC_CTX ctx; | |||
- HMAC_CTX_init(&ctx); | |||
- HMAC_Init_ex(&ctx, (unsigned char*) pKey, keyLength, EVP_sha256(), NULL); | |||
- HMAC_Update(&ctx, (unsigned char *) pData, dataLength); | |||
- HMAC_Final(&ctx, (unsigned char *) pResult, &digestLen); | |||
- HMAC_CTX_cleanup(&ctx); | |||
+ HMAC_CTX *ctx; | |||
+ ctx = HMAC_CTX_new(); | |||
+ HMAC_Init_ex(ctx, (unsigned char*) pKey, keyLength, EVP_sha256(), NULL); | |||
+ HMAC_Update(ctx, (unsigned char *) pData, dataLength); | |||
+ HMAC_Final(ctx, (unsigned char *) pResult, &digestLen); | |||
+ HMAC_CTX_free(ctx); | |||
o_assert(digestLen == 32); | |||
} | |||
--- a/sources/thelib/src/protocols/ssl/basesslprotocol.cpp | |||
+++ b/sources/thelib/src/protocols/ssl/basesslprotocol.cpp | |||
@@ -211,6 +211,7 @@ string BaseSSLProtocol::GetSSLErrors() { | |||
string BaseSSLProtocol::DumpBIO(BIO *pBIO) { | |||
string formatString; | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
formatString = "method: %p\n"; | |||
formatString += "callback: %p\n"; | |||
formatString += "cb_arg: %p\n"; | |||
@@ -240,6 +241,39 @@ string BaseSSLProtocol::DumpBIO(BIO *pBI | |||
pBIO->references, | |||
(int64_t) pBIO->num_read, | |||
(int64_t) pBIO->num_write); | |||
+#else | |||
+// Some of these are problematic in openssl >= 1.1, since | |||
+// the BIO struct is opaque. | |||
+ formatString = "method: %s\n"; | |||
+ formatString += "callback: %p\n"; | |||
+ formatString += "cb_arg: %p\n"; | |||
+ formatString += "init: %d\n"; | |||
+ formatString += "shutdown: %d\n"; | |||
+ formatString += "flags: %d\n"; | |||
+ formatString += "retry_reason: %d\n"; | |||
+ formatString += "num: %d\n"; | |||
+ formatString += "ptr: %p\n"; | |||
+ formatString += "next_bio: %p\n"; | |||
+ formatString += "prev_bio: %s\n"; | |||
+ formatString += "references: %s\n"; | |||
+ formatString += "num_read: %"PRId64"\n"; | |||
+ formatString += "num_write: %"PRId64; | |||
+ return format(formatString, | |||
+ BIO_method_name(pBIO), | |||
+ BIO_get_callback(pBIO), | |||
+ BIO_get_callback_arg(pBIO), | |||
+ BIO_get_init(pBIO), | |||
+ BIO_get_shutdown(pBIO), | |||
+ BIO_get_flags(pBIO), | |||
+ BIO_get_retry_reason(pBIO), | |||
+ BIO_get_fd(pBIO, NULL), | |||
+ BIO_get_data(pBIO), | |||
+ BIO_next(pBIO), | |||
+ "unknown", //prev_bio | |||
+ "unknown", //references | |||
+ BIO_number_read(pBIO), | |||
+ BIO_number_written(pBIO)); | |||
+#endif | |||
} | |||
void BaseSSLProtocol::InitRandGenerator() { | |||
--- /dev/null | |||
+++ b/sources/common/include/utils/misc/libcrypto-compat.h | |||
@@ -0,0 +1,25 @@ | |||
+#ifndef LIBCRYPTO_COMPAT_H | |||
+#define LIBCRYPTO_COMPAT_H | |||
+ | |||
+#include <openssl/opensslv.h> | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
+ | |||
+#include <openssl/dh.h> | |||
+#include <openssl/evp.h> | |||
+#include <openssl/hmac.h> | |||
+ | |||
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); | |||
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); | |||
+int DH_set_length(DH *dh, long length); | |||
+ | |||
+EVP_MD_CTX *EVP_MD_CTX_new(void); | |||
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx); | |||
+#define EVP_MD_CTX_reset EVP_MD_CTX_cleanup | |||
+ | |||
+HMAC_CTX *HMAC_CTX_new(void); | |||
+void HMAC_CTX_free(HMAC_CTX *ctx); | |||
+#define HMAC_CTX_reset HMAC_CTX_cleanup | |||
+ | |||
+#endif /* OPENSSL_VERSION_NUMBER */ | |||
+ | |||
+#endif /* LIBCRYPTO_COMPAT_H */ | |||
--- /dev/null | |||
+++ b/sources/common/src/utils/misc/libcrypto-compat.cpp | |||
@@ -0,0 +1,90 @@ | |||
+/* | |||
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. | |||
+ * | |||
+ * Licensed under the OpenSSL license (the "License"). You may not use | |||
+ * this file except in compliance with the License. You can obtain a copy | |||
+ * in the file LICENSE in the source distribution or at | |||
+ * https://www.openssl.org/source/license.html | |||
+ */ | |||
+ | |||
+#include "utils/misc/libcrypto-compat.h" | |||
+ | |||
+#if OPENSSL_VERSION_NUMBER < 0x10100000L | |||
+ | |||
+#include <string.h> | |||
+ | |||
+static void *OPENSSL_zalloc(size_t num) | |||
+{ | |||
+ void *ret = OPENSSL_malloc(num); | |||
+ | |||
+ if (ret != NULL) | |||
+ memset(ret, 0, num); | |||
+ return ret; | |||
+} | |||
+ | |||
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) | |||
+{ | |||
+ /* If the fields p and g in d are NULL, the corresponding input | |||
+ * parameters MUST be non-NULL. q may remain NULL. | |||
+ */ | |||
+ if ((dh->p == NULL && p == NULL) | |||
+ || (dh->g == NULL && g == NULL)) | |||
+ return 0; | |||
+ | |||
+ if (p != NULL) { | |||
+ BN_free(dh->p); | |||
+ dh->p = p; | |||
+ } | |||
+ if (q != NULL) { | |||
+ BN_free(dh->q); | |||
+ dh->q = q; | |||
+ } | |||
+ if (g != NULL) { | |||
+ BN_free(dh->g); | |||
+ dh->g = g; | |||
+ } | |||
+ | |||
+ if (q != NULL) { | |||
+ dh->length = BN_num_bits(q); | |||
+ } | |||
+ | |||
+ return 1; | |||
+} | |||
+ | |||
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) | |||
+{ | |||
+ if (pub_key != NULL) | |||
+ *pub_key = dh->pub_key; | |||
+ if (priv_key != NULL) | |||
+ *priv_key = dh->priv_key; | |||
+} | |||
+ | |||
+int DH_set_length(DH *dh, long length) | |||
+{ | |||
+ dh->length = length; | |||
+ return 1; | |||
+} | |||
+ | |||
+EVP_MD_CTX *EVP_MD_CTX_new(void) | |||
+{ | |||
+ return (EVP_MD_CTX *)OPENSSL_zalloc(sizeof(EVP_MD_CTX)); | |||
+} | |||
+ | |||
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx) | |||
+{ | |||
+ EVP_MD_CTX_cleanup(ctx); | |||
+ OPENSSL_free(ctx); | |||
+} | |||
+ | |||
+HMAC_CTX *HMAC_CTX_new(void) | |||
+{ | |||
+ return (HMAC_CTX *)OPENSSL_zalloc(sizeof(HMAC_CTX)); | |||
+} | |||
+ | |||
+void HMAC_CTX_free(HMAC_CTX *ctx) | |||
+{ | |||
+ HMAC_CTX_cleanup(ctx); | |||
+ OPENSSL_free(ctx); | |||
+} | |||
+ | |||
+#endif /* OPENSSL_VERSION_NUMBER */ |
@ -1,17 +0,0 @@ | |||
--- a/Makefile | |||
+++ b/Makefile | |||
@@ -33,12 +33,12 @@ APP_BINARY = mjpg_streamer | |||
# define the names and targets of the plugins | |||
PLUGINS = input_uvc.so | |||
-#PLUGINS += output_file.so | |||
+PLUGINS += output_file.so | |||
#PLUGINS += output_udp.so | |||
PLUGINS += output_http.so | |||
PLUGINS += input_testpicture.so | |||
#PLUGINS += output_autofocus.so | |||
-#PLUGINS += input_file.so | |||
+PLUGINS += input_file.so | |||
# PLUGINS += input_pylon.so | |||
# PLUGINS += input_megatec.so | |||
# PLUGINS += output_mars2020.so |
@ -0,0 +1,24 @@ | |||
--- a/CMakeLists.txt | |||
+++ b/CMakeLists.txt | |||
@@ -58,9 +58,9 @@ find_library(JPEG_LIB jpeg) | |||
add_subdirectory(plugins/input_file) | |||
add_subdirectory(plugins/input_http) | |||
-add_subdirectory(plugins/input_opencv) | |||
-add_subdirectory(plugins/input_raspicam) | |||
-add_subdirectory(plugins/input_ptp2) | |||
+#add_subdirectory(plugins/input_opencv) | |||
+#add_subdirectory(plugins/input_raspicam) | |||
+#add_subdirectory(plugins/input_ptp2) | |||
add_subdirectory(plugins/input_uvc) | |||
# | |||
@@ -71,7 +71,7 @@ add_subdirectory(plugins/output_file) | |||
add_subdirectory(plugins/output_http) | |||
add_subdirectory(plugins/output_rtsp) | |||
add_subdirectory(plugins/output_udp) | |||
-add_subdirectory(plugins/output_viewer) | |||
+#add_subdirectory(plugins/output_viewer) | |||
# | |||
# mjpg_streamer executable |
@ -0,0 +1,55 @@ | |||
--- a/CMakeLists.txt | |||
+++ b/CMakeLists.txt | |||
@@ -49,8 +49,7 @@ set (MJPG_STREAMER_PLUGIN_INSTALL_PATH " | |||
# Global dependencies | |||
# | |||
-find_library(JPEG_LIB jpeg) | |||
- | |||
+#find_library(JPEG_LIB jpeg) | |||
# | |||
# Input plugins | |||
--- a/plugins/input_uvc/CMakeLists.txt | |||
+++ b/plugins/input_uvc/CMakeLists.txt | |||
@@ -8,27 +8,27 @@ if (PLUGIN_INPUT_UVC) | |||
add_definitions(-DLINUX -D_GNU_SOURCE) | |||
- find_library(V4L2_LIB v4l2) | |||
+# find_library(V4L2_LIB v4l2) | |||
- if (V4L2_LIB) | |||
- add_definitions(-DUSE_LIBV4L2) | |||
- endif (V4L2_LIB) | |||
+# if (V4L2_LIB) | |||
+# add_definitions(-DUSE_LIBV4L2) | |||
+# endif (V4L2_LIB) | |||
- if (NOT JPEG_LIB) | |||
- add_definitions(-DNO_LIBJPEG) | |||
- endif (NOT JPEG_LIB) | |||
+# if (NOT JPEG_LIB) | |||
+# add_definitions(-DNO_LIBJPEG) | |||
+# endif (NOT JPEG_LIB) | |||
MJPG_STREAMER_PLUGIN_COMPILE(input_uvc dynctrl.c | |||
input_uvc.c | |||
jpeg_utils.c | |||
v4l2uvc.c) | |||
- if (V4L2_LIB) | |||
- target_link_libraries(input_uvc ${V4L2_LIB}) | |||
- endif (V4L2_LIB) | |||
+# if (V4L2_LIB) | |||
+# target_link_libraries(input_uvc ${V4L2_LIB}) | |||
+# endif (V4L2_LIB) | |||
- if (JPEG_LIB) | |||
- target_link_libraries(input_uvc ${JPEG_LIB}) | |||
- endif (JPEG_LIB) | |||
+# if (JPEG_LIB) | |||
+# target_link_libraries(input_uvc ${JPEG_LIB}) | |||
+# endif (JPEG_LIB) | |||
endif() |
@ -1,33 +0,0 @@ | |||
--- a/plugins/input_uvc/Makefile | |||
+++ b/plugins/input_uvc/Makefile | |||
@@ -13,7 +13,7 @@ OTHER_HEADERS = ../../mjpg_streamer.h .. | |||
CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC | |||
-CFLAGS += -g -DDEBUG | |||
+#CFLAGS += -g -DDEBUG | |||
ifeq ($(USE_LIBV4L2),true) | |||
LFLAGS += -lv4l2 | |||
--- a/plugins/output_file/Makefile | |||
+++ b/plugins/output_file/Makefile | |||
@@ -12,7 +12,7 @@ CC = gcc | |||
OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h | |||
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC | |||
-CFLAGS += -DDEBUG -g | |||
+#CFLAGS += -DDEBUG -g | |||
LFLAGS += -lpthread -ldl | |||
all: output_file.so | |||
--- a/plugins/output_udp/Makefile | |||
+++ b/plugins/output_udp/Makefile | |||
@@ -14,7 +14,7 @@ CC = gcc | |||
OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h | |||
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC | |||
-CFLAGS += -DDEBUG | |||
+#CFLAGS += -DDEBUG | |||
LFLAGS += -lpthread -ldl | |||
all: output_udp.so |
@ -1,11 +0,0 @@ | |||
--- a/plugins/input_uvc/v4l2uvc.c | |||
+++ b/plugins/input_uvc/v4l2uvc.c | |||
@@ -69,7 +69,7 @@ int init_videoIn(struct vdIn *vd, char * | |||
vd->videodevice = (char *) calloc(1, 16 * sizeof(char)); | |||
vd->status = (char *) calloc(1, 100 * sizeof(char)); | |||
vd->pictName = (char *) calloc(1, 80 * sizeof(char)); | |||
- snprintf(vd->videodevice, 12, "%s", device); | |||
+ snprintf(vd->videodevice, 16, "%s", device); | |||
vd->toggleAvi = 0; | |||
vd->getPict = 0; | |||
vd->signalquit = 1; |
@ -0,0 +1,24 @@ | |||
--- a/CMakeLists.txt | |||
+++ b/CMakeLists.txt | |||
@@ -18,21 +18,6 @@ include(FeatureSummary) | |||
include(mjpg_streamer_utils) | |||
# | |||
-# Get the current git hash | |||
-# | |||
-execute_process( | |||
- COMMAND git rev-parse HEAD | |||
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | |||
- RESULT_VARIABLE GIT_RESULT | |||
- OUTPUT_VARIABLE GIT_HASH | |||
- OUTPUT_STRIP_TRAILING_WHITESPACE | |||
-) | |||
- | |||
-if(GIT_RESULT EQUAL 0) | |||
- add_definitions("-DGIT_HASH=\"${GIT_HASH}\"") | |||
-endif() | |||
- | |||
-# | |||
# Options | |||
# | |||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") |
@ -1,34 +0,0 @@ | |||
--- a/Makefile | |||
+++ b/Makefile | |||
@@ -15,8 +15,8 @@ DESTDIR = /usr/local | |||
# set the compiler to use | |||
CC = gcc | |||
-SVNDEV := -D'SVN_REV="$(shell svnversion -c .)"' | |||
-CFLAGS += $(SVNDEV) | |||
+#SVNDEV := -D'SVN_REV="$(shell svnversion -c .)"' | |||
+#CFLAGS += $(SVNDEV) | |||
# general compile flags, enable all warnings to make compile more verbose | |||
CFLAGS += -DLINUX -D_GNU_SOURCE -Wall | |||
--- a/mjpg_streamer.c | |||
+++ b/mjpg_streamer.c | |||
@@ -253,15 +253,12 @@ int main(int argc, char *argv[]) | |||
/* v, version */ | |||
case 6: | |||
case 7: | |||
- printf("MJPG Streamer Version: %s\n" \ | |||
- "Compilation Date.....: %s\n" \ | |||
- "Compilation Time.....: %s\n", | |||
+ printf("MJPG Streamer Version: %s\n", | |||
#ifdef SVN_REV | |||
- SVN_REV, | |||
+ SVN_REV); | |||
#else | |||
- SOURCE_VERSION, | |||
+ SOURCE_VERSION); | |||
#endif | |||
- __DATE__, __TIME__); | |||
return 0; | |||
break; | |||
@ -1,87 +0,0 @@ | |||
From 19202b54698b343a0207d7e213448e32b8e58fc3 Mon Sep 17 00:00:00 2001 | |||
From: Olliver Schinagl <o.schinagl@ultimaker.com> | |||
Date: Wed, 29 Oct 2014 09:34:41 +0100 | |||
Subject: [PATCH 1/7] Buffer the bytesused variable from struct v4l2_buffer | |||
Starting with kernel versions 3.16, (DE)Queing of buffers has been fixed | |||
after it was leaking data for ages. in the struct v4l2_buffer is the | |||
bytesused element which indicates the size of the buffer. This however | |||
gets cleared whenever the buffer gets requeued and is thus no longer | |||
valid. | |||
This patch copies the bytesused variable so it is available until the | |||
next frame captured again. | |||
Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com> | |||
--- | |||
plugins/input_uvc/input_uvc.c | 6 +++--- | |||
plugins/input_uvc/v4l2uvc.c | 2 ++ | |||
plugins/input_uvc/v4l2uvc.h | 1 + | |||
3 files changed, 6 insertions(+), 3 deletions(-) | |||
diff --git a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c | |||
index e6c74fd..64f66cb 100644 | |||
--- a/plugins/input_uvc/input_uvc.c | |||
+++ b/plugins/input_uvc/input_uvc.c | |||
@@ -482,7 +482,7 @@ void *cam_thread(void *arg) | |||
exit(EXIT_FAILURE); | |||
} | |||
- //DBG("received frame of size: %d from plugin: %d\n", pcontext->videoIn->buf.bytesused, pcontext->id); | |||
+ //DBG("received frame of size: %d from plugin: %d\n", pcontext->videoIn->tmpbytesused, pcontext->id); | |||
/* | |||
* Workaround for broken, corrupted frames: | |||
@@ -491,7 +491,7 @@ void *cam_thread(void *arg) | |||
* For example a VGA (640x480) webcam picture is normally >= 8kByte large, | |||
* corrupted frames are smaller. | |||
*/ | |||
- if(pcontext->videoIn->buf.bytesused < minimum_size) { | |||
+ if(pcontext->videoIn->tmpbytesused < minimum_size) { | |||
DBG("dropping too small frame, assuming it as broken\n"); | |||
continue; | |||
} | |||
@@ -529,7 +529,7 @@ void *cam_thread(void *arg) | |||
} else { | |||
#endif | |||
//DBG("copying frame from input: %d\n", (int)pcontext->id); | |||
- pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused); | |||
+ pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->tmpbytesused); | |||
#ifndef NO_LIBJPEG | |||
} | |||
#endif | |||
diff --git a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c | |||
index c5a5aa4..d11510c 100644 | |||
--- a/plugins/input_uvc/v4l2uvc.c | |||
+++ b/plugins/input_uvc/v4l2uvc.c | |||
@@ -532,6 +532,7 @@ int uvcGrab(struct vdIn *vd) | |||
*/ | |||
memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused); | |||
+ vd->tmpbytesused = vd->buf.bytesused; | |||
if(debug) | |||
fprintf(stderr, "bytes in used %d \n", vd->buf.bytesused); | |||
@@ -570,6 +571,7 @@ int close_v4l2(struct vdIn *vd) | |||
if(vd->tmpbuffer) | |||
free(vd->tmpbuffer); | |||
vd->tmpbuffer = NULL; | |||
+ vd->tmpbytesused = 0; | |||
free(vd->framebuffer); | |||
vd->framebuffer = NULL; | |||
free(vd->videodevice); | |||
diff --git a/plugins/input_uvc/v4l2uvc.h b/plugins/input_uvc/v4l2uvc.h | |||
index 022c57e..2c7c8ba 100644 | |||
--- a/plugins/input_uvc/v4l2uvc.h | |||
+++ b/plugins/input_uvc/v4l2uvc.h | |||
@@ -83,6 +83,7 @@ struct vdIn { | |||
struct v4l2_requestbuffers rb; | |||
void *mem[NB_BUFFER]; | |||
unsigned char *tmpbuffer; | |||
+ int tmpbytesused; | |||
unsigned char *framebuffer; | |||
streaming_state streamingState; | |||
int grabmethod; | |||
-- | |||
1.9.1 | |||
@ -1,242 +0,0 @@ | |||
From 11b28b36a8711b53658e8bbc50435595522f91ba Mon Sep 17 00:00:00 2001 | |||
From: Olliver Schinagl <o.schinagl@ultimaker.com> | |||
Date: Wed, 29 Oct 2014 11:21:16 +0100 | |||
Subject: [PATCH 2/7] Stop leaking data via struct v4l2_buffer | |||
Before the 3.16 kernel, the v4l2_buffer was leaking data and violating | |||
its own spec. Since 3.16 this has been corrected and after calling the | |||
QBUF ioctl, the struct gets cleaned up. | |||
Right now, input_uvc assumes the buffer is valid at all times. This no | |||
longer being true, this patch removes the v4l2_buffer from the vdIn | |||
struct. Certain values are still needed outside of this buffer however, | |||
the length buffer in the buffer array 'mem' and the timestamp. These are | |||
now stored in the vdIn struct. | |||
All of this is still somewhat hackish, as a) the processing of the image | |||
should really be done inside the uvcGrab function between the queuing | |||
and dequeing of the buffers (or separate that into 3 functions, deq, q | |||
and process and call them from input_uvc). b) we are still copying the | |||
image using memcpy, which is something we don't really want and defeats | |||
the purpose of using a mmap in the first place. Changing this however | |||
requires some heavier re-architecting and in the end, may still not be avoided. | |||
More information about this bug and change can be found on the | |||
linux-media mailing list[0] with the title uvcvideo fails on 3.16 and | |||
3.17 kernels. | |||
[0] http://www.spinics.net/lists/linux-media/msg81515.html | |||
Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com> | |||
--- | |||
plugins/input_uvc/input_uvc.c | 6 ++-- | |||
plugins/input_uvc/v4l2uvc.c | 64 +++++++++++++++++++++++-------------------- | |||
plugins/input_uvc/v4l2uvc.h | 4 ++- | |||
3 files changed, 41 insertions(+), 33 deletions(-) | |||
diff --git a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c | |||
index 64f66cb..64ef56c 100644 | |||
--- a/plugins/input_uvc/input_uvc.c | |||
+++ b/plugins/input_uvc/input_uvc.c | |||
@@ -500,8 +500,8 @@ void *cam_thread(void *arg) | |||
if (pcontext->videoIn->soft_framedrop == 1) { | |||
unsigned long last = pglobal->in[pcontext->id].timestamp.tv_sec * 1000 + | |||
(pglobal->in[pcontext->id].timestamp.tv_usec/1000); // convert to ms | |||
- unsigned long current = pcontext->videoIn->buf.timestamp.tv_sec * 1000 + | |||
- pcontext->videoIn->buf.timestamp.tv_usec/1000; // convert to ms | |||
+ unsigned long current = pcontext->videoIn->tmptimestamp.tv_sec * 1000 + | |||
+ pcontext->videoIn->tmptimestamp.tv_usec/1000; // convert to ms | |||
// if the requested time did not esplashed skip the frame | |||
if ((current - last) < pcontext->videoIn->frame_period_time) { | |||
@@ -543,7 +543,7 @@ void *cam_thread(void *arg) | |||
#endif | |||
/* copy this frame's timestamp to user space */ | |||
- pglobal->in[pcontext->id].timestamp = pcontext->videoIn->buf.timestamp; | |||
+ pglobal->in[pcontext->id].timestamp = pcontext->videoIn->tmptimestamp; | |||
/* signal fresh_frame */ | |||
pthread_cond_broadcast(&pglobal->in[pcontext->id].db_update); | |||
diff --git a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c | |||
index d11510c..7ec5eec 100644 | |||
--- a/plugins/input_uvc/v4l2uvc.c | |||
+++ b/plugins/input_uvc/v4l2uvc.c | |||
@@ -217,6 +217,9 @@ static int init_v4l2(struct vdIn *vd) | |||
{ | |||
int i; | |||
int ret = 0; | |||
+ struct v4l2_buffer buf; | |||
+ | |||
+ | |||
if((vd->fd = OPEN_VIDEO(vd->videodevice, O_RDWR)) == -1) { | |||
perror("ERROR opening V4L interface"); | |||
DBG("errno: %d", errno); | |||
@@ -375,26 +378,27 @@ static int init_v4l2(struct vdIn *vd) | |||
* map the buffers | |||
*/ | |||
for(i = 0; i < NB_BUFFER; i++) { | |||
- memset(&vd->buf, 0, sizeof(struct v4l2_buffer)); | |||
- vd->buf.index = i; | |||
- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
- vd->buf.memory = V4L2_MEMORY_MMAP; | |||
- ret = xioctl(vd->fd, VIDIOC_QUERYBUF, &vd->buf); | |||
+ memset(&buf, 0, sizeof(struct v4l2_buffer)); | |||
+ buf.index = i; | |||
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
+ buf.memory = V4L2_MEMORY_MMAP; | |||
+ ret = xioctl(vd->fd, VIDIOC_QUERYBUF, &buf); | |||
if(ret < 0) { | |||
perror("Unable to query buffer"); | |||
goto fatal; | |||
} | |||
if(debug) | |||
- fprintf(stderr, "length: %u offset: %u\n", vd->buf.length, vd->buf.m.offset); | |||
+ fprintf(stderr, "length: %u offset: %u\n", buf.length, buf.m.offset); | |||
vd->mem[i] = mmap(0 /* start anywhere */ , | |||
- vd->buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd, | |||
- vd->buf.m.offset); | |||
+ buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd, | |||
+ buf.m.offset); | |||
if(vd->mem[i] == MAP_FAILED) { | |||
perror("Unable to map buffer"); | |||
goto fatal; | |||
} | |||
+ vd->memlength[i] = buf.length; | |||
if(debug) | |||
fprintf(stderr, "Buffer mapped at address %p.\n", vd->mem[i]); | |||
} | |||
@@ -403,11 +407,11 @@ static int init_v4l2(struct vdIn *vd) | |||
* Queue the buffers. | |||
*/ | |||
for(i = 0; i < NB_BUFFER; ++i) { | |||
- memset(&vd->buf, 0, sizeof(struct v4l2_buffer)); | |||
- vd->buf.index = i; | |||
- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
- vd->buf.memory = V4L2_MEMORY_MMAP; | |||
- ret = xioctl(vd->fd, VIDIOC_QBUF, &vd->buf); | |||
+ memset(&buf, 0, sizeof(struct v4l2_buffer)); | |||
+ buf.index = i; | |||
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
+ buf.memory = V4L2_MEMORY_MMAP; | |||
+ ret = xioctl(vd->fd, VIDIOC_QBUF, &buf); | |||
if(ret < 0) { | |||
perror("Unable to queue buffer"); | |||
goto fatal;; | |||
@@ -499,17 +503,18 @@ int memcpy_picture(unsigned char *out, unsigned char *buf, int size) | |||
int uvcGrab(struct vdIn *vd) | |||
{ | |||
#define HEADERFRAME1 0xaf | |||
+ struct v4l2_buffer buf; | |||
int ret; | |||
if(vd->streamingState == STREAMING_OFF) { | |||
if(video_enable(vd)) | |||
goto err; | |||
} | |||
- memset(&vd->buf, 0, sizeof(struct v4l2_buffer)); | |||
- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
- vd->buf.memory = V4L2_MEMORY_MMAP; | |||
+ memset(&buf, 0, sizeof(struct v4l2_buffer)); | |||
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
+ buf.memory = V4L2_MEMORY_MMAP; | |||
- ret = xioctl(vd->fd, VIDIOC_DQBUF, &vd->buf); | |||
+ ret = xioctl(vd->fd, VIDIOC_DQBUF, &buf); | |||
if(ret < 0) { | |||
perror("Unable to dequeue buffer"); | |||
goto err; | |||
@@ -517,33 +522,34 @@ int uvcGrab(struct vdIn *vd) | |||
switch(vd->formatIn) { | |||
case V4L2_PIX_FMT_MJPEG: | |||
- if(vd->buf.bytesused <= HEADERFRAME1) { | |||
+ if(buf.bytesused <= HEADERFRAME1) { | |||
/* Prevent crash | |||
* on empty image */ | |||
fprintf(stderr, "Ignoring empty buffer ...\n"); | |||
return 0; | |||
} | |||
- /* memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused); | |||
+ /* memcpy(vd->tmpbuffer, vd->mem[buf.index], buf.bytesused); | |||
- memcpy (vd->tmpbuffer, vd->mem[vd->buf.index], HEADERFRAME1); | |||
+ memcpy (vd->tmpbuffer, vd->mem[buf.index], HEADERFRAME1); | |||
memcpy (vd->tmpbuffer + HEADERFRAME1, dht_data, sizeof(dht_data)); | |||
- memcpy (vd->tmpbuffer + HEADERFRAME1 + sizeof(dht_data), vd->mem[vd->buf.index] + HEADERFRAME1, (vd->buf.bytesused - HEADERFRAME1)); | |||
+ memcpy (vd->tmpbuffer + HEADERFRAME1 + sizeof(dht_data), vd->mem[buf.index] + HEADERFRAME1, (buf.bytesused - HEADERFRAME1)); | |||
*/ | |||
- memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused); | |||
- vd->tmpbytesused = vd->buf.bytesused; | |||
+ memcpy(vd->tmpbuffer, vd->mem[buf.index], buf.bytesused); | |||
+ vd->tmpbytesused = buf.bytesused; | |||
+ vd->tmptimestamp = buf.timestamp; | |||
if(debug) | |||
- fprintf(stderr, "bytes in used %d \n", vd->buf.bytesused); | |||
+ fprintf(stderr, "bytes in used %d \n", buf.bytesused); | |||
break; | |||
case V4L2_PIX_FMT_RGB565: | |||
case V4L2_PIX_FMT_YUYV: | |||
case V4L2_PIX_FMT_RGB24: | |||
- if(vd->buf.bytesused > vd->framesizeIn) | |||
- memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->framesizeIn); | |||
+ if(buf.bytesused > vd->framesizeIn) | |||
+ memcpy(vd->framebuffer, vd->mem[buf.index], (size_t) vd->framesizeIn); | |||
else | |||
- memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->buf.bytesused); | |||
+ memcpy(vd->framebuffer, vd->mem[buf.index], (size_t) buf.bytesused); | |||
break; | |||
default: | |||
@@ -551,7 +557,7 @@ int uvcGrab(struct vdIn *vd) | |||
break; | |||
} | |||
- ret = xioctl(vd->fd, VIDIOC_QBUF, &vd->buf); | |||
+ ret = xioctl(vd->fd, VIDIOC_QBUF, &buf); | |||
if(ret < 0) { | |||
perror("Unable to requeue buffer"); | |||
goto err; | |||
@@ -947,7 +953,7 @@ int setResolution(struct vdIn *vd, int width, int height) | |||
DBG("Unmap buffers\n"); | |||
int i; | |||
for(i = 0; i < NB_BUFFER; i++) | |||
- munmap(vd->mem[i], vd->buf.length); | |||
+ munmap(vd->mem[i], vd->memlength[i]); | |||
if(CLOSE_VIDEO(vd->fd) == 0) { | |||
DBG("Device closed successfully\n"); | |||
diff --git a/plugins/input_uvc/v4l2uvc.h b/plugins/input_uvc/v4l2uvc.h | |||
index 2c7c8ba..e625957 100644 | |||
--- a/plugins/input_uvc/v4l2uvc.h | |||
+++ b/plugins/input_uvc/v4l2uvc.h | |||
@@ -35,6 +35,7 @@ | |||
#include <sys/ioctl.h> | |||
#include <sys/mman.h> | |||
#include <sys/select.h> | |||
+#include <sys/time.h> | |||
#include <linux/types.h> /* for videodev2.h */ | |||
#include <linux/videodev2.h> | |||
@@ -79,11 +80,12 @@ struct vdIn { | |||
char *pictName; | |||
struct v4l2_capability cap; | |||
struct v4l2_format fmt; | |||
- struct v4l2_buffer buf; | |||
struct v4l2_requestbuffers rb; | |||
void *mem[NB_BUFFER]; | |||
+ int memlength[NB_BUFFER]; | |||
unsigned char *tmpbuffer; | |||
int tmpbytesused; | |||
+ struct timeval tmptimestamp; | |||
unsigned char *framebuffer; | |||
streaming_state streamingState; | |||
int grabmethod; | |||
-- | |||
1.9.1 | |||
@ -1,58 +0,0 @@ | |||
Binary files a/ipkg-ar71xx/mjpg-streamer/usr/lib/input_uvc.so and b/ipkg-ar71xx/mjpg-streamer/usr/lib/input_uvc.so differ | |||
diff -ur a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c | |||
--- a/plugins/input_uvc/input_uvc.c 2015-03-02 09:14:05.000000000 +0200 | |||
+++ b/plugins/input_uvc/input_uvc.c 2015-03-02 09:18:22.000000000 +0200 | |||
@@ -311,6 +311,10 @@ | |||
} | |||
memset(cams[id].videoIn, 0, sizeof(struct vdIn)); | |||
+ /* Non-MJPEG formats seem to fail with unlimited FPS */ | |||
+ if (format != V4L2_PIX_FMT_MJPEG && fps == -1) | |||
+ fps = 15; | |||
+ | |||
/* display the parsed values */ | |||
IPRINT("Using V4L2 device.: %s\n", dev); | |||
IPRINT("Desired Resolution: %i x %i\n", width, height); | |||
diff -ur a/plugins/input_uvc/jpeg_utils.c b/plugins/input_uvc/jpeg_utils.c | |||
--- a/plugins/input_uvc/jpeg_utils.c 2015-03-02 09:17:02.000000000 +0300 | |||
+++ b/plugins/input_uvc/jpeg_utils.c 2015-03-02 09:25:18.000000000 +0200 | |||
@@ -198,7 +198,7 @@ | |||
} | |||
row_pointer = (JSAMPROW*)line_buffer; | |||
- jpeg_write_scanlines(&cinfo, row_pointer, 1); | |||
+ jpeg_write_scanlines(&cinfo, &row_pointer, 1); | |||
} | |||
} else if (vd->formatIn == V4L2_PIX_FMT_RGB565) { | |||
while(cinfo.next_scanline < vd->height) { | |||
@@ -220,7 +220,7 @@ | |||
} | |||
row_pointer = (JSAMPROW*)line_buffer; | |||
- jpeg_write_scanlines(&cinfo, row_pointer, 1); | |||
+ jpeg_write_scanlines(&cinfo, &row_pointer, 1); | |||
} | |||
} else if (vd->formatIn == V4L2_PIX_FMT_RGB24) { | |||
jpeg_write_scanlines(&cinfo, (JSAMPROW*)vd->framebuffer, vd->height); | |||
diff -ur a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c | |||
--- a/plugins/input_uvc/v4l2uvc.c 2015-03-02 09:14:05.000000000 +0200 | |||
+++ b/plugins/input_uvc/v4l2uvc.c 2015-03-02 09:22:09.000000000 +0200 | |||
@@ -338,11 +338,15 @@ | |||
vd->frame_period_time = 1000/vd->fps; // calcualate frame period time in ms | |||
IPRINT("Frame period time ......: %ld ms\n", vd->frame_period_time); | |||
- // set FPS to maximum in order to minimize the lagging | |||
memset(setfps, 0, sizeof(struct v4l2_streamparm)); | |||
setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |||
setfps->parm.capture.timeperframe.numerator = 1; | |||
- setfps->parm.capture.timeperframe.denominator = 255; | |||
+ if (vd->formatIn == V4L2_PIX_FMT_MJPEG) | |||
+ // set FPS to maximum in order to minimize the lagging | |||
+ setfps->parm.capture.timeperframe.denominator = 255; | |||
+ else | |||
+ setfps->parm.capture.timeperframe.denominator = vd->fps; | |||
+ | |||
ret = xioctl(vd->fd, VIDIOC_S_PARM, setfps); | |||
if (ret) { | |||
perror("Unable to set the FPS\n"); | |||
@ -1,11 +0,0 @@ | |||
--- a/plugins/input_uvc/v4l2uvc.c | |||
+++ b/plugins/input_uvc/v4l2uvc.c | |||
@@ -130,7 +130,7 @@ int init_videoIn(struct vdIn *vd, char * | |||
return -1; | |||
} | |||
- memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(input_format)); | |||
+ memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(struct v4l2_fmtdesc)); | |||
if(fmtdesc.pixelformat == format) | |||
pglobal->in[id].currentFormat = pglobal->in[id].formatCount; |
@ -1,33 +0,0 @@ | |||
From bfb1a652dbf897dc065d2a1414296eb145a2224b Mon Sep 17 00:00:00 2001 | |||
From: Moritz Warning <moritzwarning@web.de> | |||
Date: Mon, 23 Apr 2018 22:31:03 +0200 | |||
Subject: [PATCH 3/4] remove -march=armv5 | |||
--- | |||
make-linux.mk | 8 ++++---- | |||
1 file changed, 4 insertions(+), 4 deletions(-) | |||
diff --git a/make-linux.mk b/make-linux.mk | |||
index add1d3ae..49e14f70 100644 | |||
--- a/make-linux.mk | |||
+++ b/make-linux.mk | |||
@@ -229,12 +229,12 @@ endif | |||
# ARM32 hell -- use conservative CFLAGS | |||
ifeq ($(ZT_ARCHITECTURE),3) | |||
ifeq ($(shell if [ -e /usr/bin/dpkg ]; then dpkg --print-architecture; fi),armel) | |||
- override CFLAGS+=-march=armv5 -mfloat-abi=soft -msoft-float -mno-unaligned-access -marm | |||
- override CXXFLAGS+=-march=armv5 -mfloat-abi=soft -msoft-float -mno-unaligned-access -marm | |||
+ override CFLAGS+=-mfloat-abi=soft -msoft-float -mno-unaligned-access -marm | |||
+ override CXXFLAGS+=-mfloat-abi=soft -msoft-float -mno-unaligned-access -marm | |||
ZT_USE_ARM32_NEON_ASM_CRYPTO=0 | |||
else | |||
- override CFLAGS+=-march=armv5 -mno-unaligned-access -marm | |||
- override CXXFLAGS+=-march=armv5 -mno-unaligned-access -marm | |||
+ override CFLAGS+=-mno-unaligned-access -marm | |||
+ override CXXFLAGS+=-mno-unaligned-access -marm | |||
endif | |||
endif | |||
-- | |||
2.17.0 | |||