@ -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 | |||||